Loading analysis/analysisview.py +22 −77 Original line number Original line Diff line number Diff line Loading @@ -30,7 +30,7 @@ from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure from matplotlib.figure import Figure from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar from .analysiswidgets import ExpExcelDialog, AdditiveViewer from .analysiswidgets import ExpExcelDialog, AdditiveViewer, ParticleTypeView from .loadresults import LoadWITecResults from .loadresults import LoadWITecResults from .particleeditor import ParticleEditor from .particleeditor import ParticleEditor from .database import DataBaseWindow from .database import DataBaseWindow Loading Loading @@ -67,11 +67,10 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.currentSpectrumIndex = 0 self.currentSpectrumIndex = 0 self.lastSpectrumInFocus = None self.lastSpectrumInFocus = None self.typeHistogramCanvas = FigureCanvas(Figure()) self.typeHistogram = ParticleTypeView(self) self.typeHistogram.indexClicked.connect(self.getAdditivePlot) self.sizeHistogramCanvas = FigureCanvas(Figure()) self.sizeHistogramCanvas = FigureCanvas(Figure()) self.typeHist_ax = self.typeHistogramCanvas.figure.subplots() self.typeHist_ax.axis('off') sizeHistGroup = QtWidgets.QGroupBox() sizeHistGroup = QtWidgets.QGroupBox() sizeHistLayout = QtWidgets.QHBoxLayout() sizeHistLayout = QtWidgets.QHBoxLayout() self.sizeHist_ax = self.sizeHistogramCanvas.figure.subplots() self.sizeHist_ax = self.sizeHistogramCanvas.figure.subplots() Loading Loading @@ -107,7 +106,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): splitter1.addWidget(sizeHistGroup) splitter1.addWidget(sizeHistGroup) splitter2 = QtWidgets.QSplitter(QtCore.Qt.Horizontal) splitter2 = QtWidgets.QSplitter(QtCore.Qt.Horizontal) splitter2.addWidget(splitter1) splitter2.addWidget(splitter1) splitter2.addWidget(self.typeHistogramCanvas) splitter2.addWidget(self.typeHistogram) splitter2.setSizes([300, 150]) splitter2.setSizes([300, 150]) self.navigationGroup = QtWidgets.QGroupBox('Navigate through polymers') self.navigationGroup = QtWidgets.QGroupBox('Navigate through polymers') Loading Loading @@ -343,11 +342,12 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.importWindow = LoadWITecResults(self.datastats, self) self.importWindow = LoadWITecResults(self.datastats, self) self.importWindow.exec() self.importWindow.exec() def getAdditivePlot(self, event): @QtCore.pyqtSlot(int) clickedindex = int(np.round(event.xdata)) def getAdditivePlot(self, clickedindex): polymer = self.datastats.typehistogram[clickedindex][0] #get the polymer name, that was clicked on polymer = self.datastats.typehistogram[clickedindex][0] #get the polymer name, that was clicked on if len(self.datastats.sorted_additives[clickedindex]) > 0: if self.datastats.sorted_additives is not None and \ len(self.datastats.sorted_additives[clickedindex]) > 0: self.additivePlot = AdditiveViewer(polymer, self.datastats.sorted_additives[clickedindex]) self.additivePlot = AdditiveViewer(polymer, self.datastats.sorted_additives[clickedindex]) self.additivePlot.show() self.additivePlot.show() Loading Loading @@ -419,10 +419,6 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.menuLayout.addWidget(self.resultScrollarea) self.menuLayout.addWidget(self.resultScrollarea) if self.datastats.currentAdditives is not None: self.typeHistogramCanvas.setCursor(QtGui.QCursor(QtCore.Qt.WhatsThisCursor)) self.typeHistogramCanvas.mpl_connect('button_press_event', self.getAdditivePlot) self.expExcelAct.setDisabled(False) self.expExcelAct.setDisabled(False) if sqlEnabled: if sqlEnabled: self.expSQLAct.setDisabled(False) self.expSQLAct.setDisabled(False) Loading Loading @@ -568,37 +564,15 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.updateSpecPlot() self.updateSpecPlot() def updateHistogram(self): def updateHistogram(self): self.sizeHist_ax.clear() self.typeHist_ax.clear() self.typeHist_ax.axis('on') self.sizeHist_ax.axis('on') #draw the general histogram #draw the general histogram colorList = [] colorList = [] if self.selOverlayAct.isChecked(): abundancyList = [] abundancyList = [] for index, checkbox in enumerate(self.polymerCheckBoxes): labelList = [] if checkbox.isChecked(): abundancyList.append(self.datastats.typehistogram[index][1]) curColor = self.getColorFromName(self.datastats.typehistogram[index][0], base255 = False) colorList.append(curColor) else: abundancyList = [i[1] for i in self.datastats.typehistogram] for polymer in self.datastats.typehistogram: curColor = self.getColorFromName(polymer[0], base255 = False) colorList.append(curColor) self.typeHist_ax.barh(range(len(abundancyList)), abundancyList, color=colorList) itemsInPlot = (len(abundancyList) if len(abundancyList) < self.dispResultSpinBox.value() else self.dispResultSpinBox.value()) self.typeHist_ax.set_ylim([itemsInPlot, -1]) #plot in inverse order (have index 0 (highest abundancy) at top) ###add text labels self.histPlotTextLabels = [] y_label_position = 0 for index, i in enumerate(self.datastats.typehistogram): for index, i in enumerate(self.datastats.typehistogram): if not self.selOverlayAct.isChecked() or self.polymerCheckBoxes[index].isChecked(): if not self.selOverlayAct.isChecked() or self.polymerCheckBoxes[index].isChecked(): abundancyList.append(self.datastats.typehistogram[index][1]) curColor = self.getColorFromName(self.datastats.typehistogram[index][0]) colorList.append(QtGui.QColor(*curColor)) if self.datastats.sorted_additives is None: if self.datastats.sorted_additives is None: numads = '' numads = '' else: else: Loading @@ -609,46 +583,17 @@ class ParticleAnalysis(QtWidgets.QMainWindow): numads = '(' + str(numads) + ')' numads = '(' + str(numads) + ')' numpolymers = i[1] numpolymers = i[1] label = ('{} x ' + self.datastats.typehistogram[index][0] + ' {}').format(numpolymers, numads) label = ('{} x ' + self.datastats.typehistogram[index][0] + ' {}').format(numpolymers, numads) x_label_position = self.typeHist_ax.get_xlim()[1]*0.05 labelList.append(label) self.histPlotTextLabels.append(self.typeHist_ax.text(x_label_position, y_label_position, label, fontsize = 15, rotation = 0, verticalalignment = 'bottom')) y_label_position += 1 for label in self.histPlotTextLabels: pos = label.get_position() curLimits = self.typeHist_ax.get_ylim() if curLimits[1] < pos[1] < curLimits[0]: label.set_alpha(1) else: label.set_alpha(0) self.typeHist_ax.set_title('Polymer Type Distribution', fontsize = 15) self.typeHist_ax.tick_params(axis='y', which='both', left=False, labelleft=False) self.typeHist_ax.tick_params(axis='both', which='both', labelsize=15) self.typeHist_ax.set_ylabel('Polymer Type', fontsize = 15) self.typeHist_ax.set_xlabel('Number', fontsize = 15) if len(self.datastats.typehistogram) > self.dispResultSpinBox.value(): def wheelScroll(event): step = -0.05*event.step*self.dispResultSpinBox.value() ymin, ymax = self.typeHist_ax.get_ylim() if ymin > ymax: ymin, ymax = ymax, ymin self.typeHist_ax.set_ylim([ymax+step, ymin+step]) for label in self.histPlotTextLabels: pos = label.get_position() if ymin+step < pos[1] < ymax+step: label.set_alpha(1) else: label.set_alpha(0) self.typeHist_ax.figure.canvas.draw() self.typeHistogramCanvas.mpl_connect('scroll_event', wheelScroll) self.typeHist_ax.figure.canvas.draw() print("abundancyList:", abundancyList) print("labelList:", labelList) print("colorList:", colorList) self.typeHistogram.updateTypes(list(zip(abundancyList, labelList, colorList))) #general size histogram #general size histogram self.sizeHist_ax.clear() self.sizeHist_ax.axis('on') self.bins = np.logspace(0.1, 3, 20) self.bins = np.logspace(0.1, 3, 20) self.sizes = [i[0] if np.isnan(i[2]) else i[2] for i in self.datastats.getParticleStats()] #extract long size (if ellipse fit is nan -> box fit) self.sizes = [i[0] if np.isnan(i[2]) else i[2] for i in self.datastats.getParticleStats()] #extract long size (if ellipse fit is nan -> box fit) sizehist = np.histogram(self.sizes, self.bins) sizehist = np.histogram(self.sizes, self.bins) Loading analysis/analysiswidgets.py +72 −2 Original line number Original line Diff line number Diff line Loading @@ -19,7 +19,7 @@ along with this program, see COPYING. If not, see <https://www.gnu.org/licenses/>. If not, see <https://www.gnu.org/licenses/>. """ """ from PyQt5 import QtWidgets from PyQt5 import QtWidgets, QtGui, QtCore import numpy as np import numpy as np import pandas as pd import pandas as pd import os import os Loading Loading @@ -202,3 +202,73 @@ class AdditiveViewer(QtWidgets.QWidget): self.ax.hist(sortedAdditives) self.ax.hist(sortedAdditives) self.ax.set_ylabel('Number', fontsize = 15) self.ax.set_ylabel('Number', fontsize = 15) self.ax.tick_params(axis='both', which='both', labelsize=15) self.ax.tick_params(axis='both', which='both', labelsize=15) class ParticleIndicator(QtWidgets.QPushButton): def __init__(self, number, numtotal, color, text, parent=None): super().__init__(parent) self.number = number self.numtotal = numtotal self.color = color self.text = text self.setFixedHeight(30) def paintEvent(self, event): r = self.number/self.numtotal width = self.width() height = self.height() qp = QtGui.QPainter() qp.begin(self) qp.fillRect(self.rect(), QtCore.Qt.white) qp.setPen(self.color) qp.setBrush(self.color) qp.drawRoundedRect(0, 0, int(width*r), height, 5. ,5.) qp.setPen(QtCore.Qt.black) qp.setBrush(QtCore.Qt.NoBrush) qp.drawRoundedRect(0, 0, width, height, 5. ,5.) qp.drawText(self.rect(), QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter, self.text) qp.end() class ParticleTypeView(QtWidgets.QScrollArea): indexClicked = QtCore.pyqtSignal(int) def __init__(self, parent=None): super().__init__(parent) self.view = QtWidgets.QWidget(self) self.view.setCursor(QtGui.QCursor(QtCore.Qt.WhatsThisCursor)) self.view.setMinimumWidth(250) group = QtWidgets.QGroupBox('Polymer Type Distribution', self.view) self.indicatorbox = QtWidgets.QVBoxLayout() self.indicatorbox.setContentsMargins(5,5,5,5) group.setLayout(self.indicatorbox) hbox = QtWidgets.QHBoxLayout() hbox.addWidget(group) self.view.setLayout(hbox) self.setWidgetResizable(True) self.setWidget(self.view) self.setAlignment(QtCore.Qt.AlignHCenter) def updateTypes(self, types): print("Updating polymer type view", flush=True) for i in range(self.indicatorbox.count()): self.indicatorbox.takeAt(0) numtotal = sum([num for num, text, color in types]) def getIndexFunction(index): return lambda : self.indexClicked.emit(index) for index, entry in enumerate(types): num, text, color = entry print("num, text, color:", num, text, color, flush=True) pi = ParticleIndicator(num, numtotal, color, text) self.indicatorbox.addWidget(pi) pi.clicked.connect(getIndexFunction(index)) self.indicatorbox.addStretch() self.view.update() No newline at end of file Loading
analysis/analysisview.py +22 −77 Original line number Original line Diff line number Diff line Loading @@ -30,7 +30,7 @@ from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure from matplotlib.figure import Figure from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar from .analysiswidgets import ExpExcelDialog, AdditiveViewer from .analysiswidgets import ExpExcelDialog, AdditiveViewer, ParticleTypeView from .loadresults import LoadWITecResults from .loadresults import LoadWITecResults from .particleeditor import ParticleEditor from .particleeditor import ParticleEditor from .database import DataBaseWindow from .database import DataBaseWindow Loading Loading @@ -67,11 +67,10 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.currentSpectrumIndex = 0 self.currentSpectrumIndex = 0 self.lastSpectrumInFocus = None self.lastSpectrumInFocus = None self.typeHistogramCanvas = FigureCanvas(Figure()) self.typeHistogram = ParticleTypeView(self) self.typeHistogram.indexClicked.connect(self.getAdditivePlot) self.sizeHistogramCanvas = FigureCanvas(Figure()) self.sizeHistogramCanvas = FigureCanvas(Figure()) self.typeHist_ax = self.typeHistogramCanvas.figure.subplots() self.typeHist_ax.axis('off') sizeHistGroup = QtWidgets.QGroupBox() sizeHistGroup = QtWidgets.QGroupBox() sizeHistLayout = QtWidgets.QHBoxLayout() sizeHistLayout = QtWidgets.QHBoxLayout() self.sizeHist_ax = self.sizeHistogramCanvas.figure.subplots() self.sizeHist_ax = self.sizeHistogramCanvas.figure.subplots() Loading Loading @@ -107,7 +106,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): splitter1.addWidget(sizeHistGroup) splitter1.addWidget(sizeHistGroup) splitter2 = QtWidgets.QSplitter(QtCore.Qt.Horizontal) splitter2 = QtWidgets.QSplitter(QtCore.Qt.Horizontal) splitter2.addWidget(splitter1) splitter2.addWidget(splitter1) splitter2.addWidget(self.typeHistogramCanvas) splitter2.addWidget(self.typeHistogram) splitter2.setSizes([300, 150]) splitter2.setSizes([300, 150]) self.navigationGroup = QtWidgets.QGroupBox('Navigate through polymers') self.navigationGroup = QtWidgets.QGroupBox('Navigate through polymers') Loading Loading @@ -343,11 +342,12 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.importWindow = LoadWITecResults(self.datastats, self) self.importWindow = LoadWITecResults(self.datastats, self) self.importWindow.exec() self.importWindow.exec() def getAdditivePlot(self, event): @QtCore.pyqtSlot(int) clickedindex = int(np.round(event.xdata)) def getAdditivePlot(self, clickedindex): polymer = self.datastats.typehistogram[clickedindex][0] #get the polymer name, that was clicked on polymer = self.datastats.typehistogram[clickedindex][0] #get the polymer name, that was clicked on if len(self.datastats.sorted_additives[clickedindex]) > 0: if self.datastats.sorted_additives is not None and \ len(self.datastats.sorted_additives[clickedindex]) > 0: self.additivePlot = AdditiveViewer(polymer, self.datastats.sorted_additives[clickedindex]) self.additivePlot = AdditiveViewer(polymer, self.datastats.sorted_additives[clickedindex]) self.additivePlot.show() self.additivePlot.show() Loading Loading @@ -419,10 +419,6 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.menuLayout.addWidget(self.resultScrollarea) self.menuLayout.addWidget(self.resultScrollarea) if self.datastats.currentAdditives is not None: self.typeHistogramCanvas.setCursor(QtGui.QCursor(QtCore.Qt.WhatsThisCursor)) self.typeHistogramCanvas.mpl_connect('button_press_event', self.getAdditivePlot) self.expExcelAct.setDisabled(False) self.expExcelAct.setDisabled(False) if sqlEnabled: if sqlEnabled: self.expSQLAct.setDisabled(False) self.expSQLAct.setDisabled(False) Loading Loading @@ -568,37 +564,15 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.updateSpecPlot() self.updateSpecPlot() def updateHistogram(self): def updateHistogram(self): self.sizeHist_ax.clear() self.typeHist_ax.clear() self.typeHist_ax.axis('on') self.sizeHist_ax.axis('on') #draw the general histogram #draw the general histogram colorList = [] colorList = [] if self.selOverlayAct.isChecked(): abundancyList = [] abundancyList = [] for index, checkbox in enumerate(self.polymerCheckBoxes): labelList = [] if checkbox.isChecked(): abundancyList.append(self.datastats.typehistogram[index][1]) curColor = self.getColorFromName(self.datastats.typehistogram[index][0], base255 = False) colorList.append(curColor) else: abundancyList = [i[1] for i in self.datastats.typehistogram] for polymer in self.datastats.typehistogram: curColor = self.getColorFromName(polymer[0], base255 = False) colorList.append(curColor) self.typeHist_ax.barh(range(len(abundancyList)), abundancyList, color=colorList) itemsInPlot = (len(abundancyList) if len(abundancyList) < self.dispResultSpinBox.value() else self.dispResultSpinBox.value()) self.typeHist_ax.set_ylim([itemsInPlot, -1]) #plot in inverse order (have index 0 (highest abundancy) at top) ###add text labels self.histPlotTextLabels = [] y_label_position = 0 for index, i in enumerate(self.datastats.typehistogram): for index, i in enumerate(self.datastats.typehistogram): if not self.selOverlayAct.isChecked() or self.polymerCheckBoxes[index].isChecked(): if not self.selOverlayAct.isChecked() or self.polymerCheckBoxes[index].isChecked(): abundancyList.append(self.datastats.typehistogram[index][1]) curColor = self.getColorFromName(self.datastats.typehistogram[index][0]) colorList.append(QtGui.QColor(*curColor)) if self.datastats.sorted_additives is None: if self.datastats.sorted_additives is None: numads = '' numads = '' else: else: Loading @@ -609,46 +583,17 @@ class ParticleAnalysis(QtWidgets.QMainWindow): numads = '(' + str(numads) + ')' numads = '(' + str(numads) + ')' numpolymers = i[1] numpolymers = i[1] label = ('{} x ' + self.datastats.typehistogram[index][0] + ' {}').format(numpolymers, numads) label = ('{} x ' + self.datastats.typehistogram[index][0] + ' {}').format(numpolymers, numads) x_label_position = self.typeHist_ax.get_xlim()[1]*0.05 labelList.append(label) self.histPlotTextLabels.append(self.typeHist_ax.text(x_label_position, y_label_position, label, fontsize = 15, rotation = 0, verticalalignment = 'bottom')) y_label_position += 1 for label in self.histPlotTextLabels: pos = label.get_position() curLimits = self.typeHist_ax.get_ylim() if curLimits[1] < pos[1] < curLimits[0]: label.set_alpha(1) else: label.set_alpha(0) self.typeHist_ax.set_title('Polymer Type Distribution', fontsize = 15) self.typeHist_ax.tick_params(axis='y', which='both', left=False, labelleft=False) self.typeHist_ax.tick_params(axis='both', which='both', labelsize=15) self.typeHist_ax.set_ylabel('Polymer Type', fontsize = 15) self.typeHist_ax.set_xlabel('Number', fontsize = 15) if len(self.datastats.typehistogram) > self.dispResultSpinBox.value(): def wheelScroll(event): step = -0.05*event.step*self.dispResultSpinBox.value() ymin, ymax = self.typeHist_ax.get_ylim() if ymin > ymax: ymin, ymax = ymax, ymin self.typeHist_ax.set_ylim([ymax+step, ymin+step]) for label in self.histPlotTextLabels: pos = label.get_position() if ymin+step < pos[1] < ymax+step: label.set_alpha(1) else: label.set_alpha(0) self.typeHist_ax.figure.canvas.draw() self.typeHistogramCanvas.mpl_connect('scroll_event', wheelScroll) self.typeHist_ax.figure.canvas.draw() print("abundancyList:", abundancyList) print("labelList:", labelList) print("colorList:", colorList) self.typeHistogram.updateTypes(list(zip(abundancyList, labelList, colorList))) #general size histogram #general size histogram self.sizeHist_ax.clear() self.sizeHist_ax.axis('on') self.bins = np.logspace(0.1, 3, 20) self.bins = np.logspace(0.1, 3, 20) self.sizes = [i[0] if np.isnan(i[2]) else i[2] for i in self.datastats.getParticleStats()] #extract long size (if ellipse fit is nan -> box fit) self.sizes = [i[0] if np.isnan(i[2]) else i[2] for i in self.datastats.getParticleStats()] #extract long size (if ellipse fit is nan -> box fit) sizehist = np.histogram(self.sizes, self.bins) sizehist = np.histogram(self.sizes, self.bins) Loading
analysis/analysiswidgets.py +72 −2 Original line number Original line Diff line number Diff line Loading @@ -19,7 +19,7 @@ along with this program, see COPYING. If not, see <https://www.gnu.org/licenses/>. If not, see <https://www.gnu.org/licenses/>. """ """ from PyQt5 import QtWidgets from PyQt5 import QtWidgets, QtGui, QtCore import numpy as np import numpy as np import pandas as pd import pandas as pd import os import os Loading Loading @@ -202,3 +202,73 @@ class AdditiveViewer(QtWidgets.QWidget): self.ax.hist(sortedAdditives) self.ax.hist(sortedAdditives) self.ax.set_ylabel('Number', fontsize = 15) self.ax.set_ylabel('Number', fontsize = 15) self.ax.tick_params(axis='both', which='both', labelsize=15) self.ax.tick_params(axis='both', which='both', labelsize=15) class ParticleIndicator(QtWidgets.QPushButton): def __init__(self, number, numtotal, color, text, parent=None): super().__init__(parent) self.number = number self.numtotal = numtotal self.color = color self.text = text self.setFixedHeight(30) def paintEvent(self, event): r = self.number/self.numtotal width = self.width() height = self.height() qp = QtGui.QPainter() qp.begin(self) qp.fillRect(self.rect(), QtCore.Qt.white) qp.setPen(self.color) qp.setBrush(self.color) qp.drawRoundedRect(0, 0, int(width*r), height, 5. ,5.) qp.setPen(QtCore.Qt.black) qp.setBrush(QtCore.Qt.NoBrush) qp.drawRoundedRect(0, 0, width, height, 5. ,5.) qp.drawText(self.rect(), QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter, self.text) qp.end() class ParticleTypeView(QtWidgets.QScrollArea): indexClicked = QtCore.pyqtSignal(int) def __init__(self, parent=None): super().__init__(parent) self.view = QtWidgets.QWidget(self) self.view.setCursor(QtGui.QCursor(QtCore.Qt.WhatsThisCursor)) self.view.setMinimumWidth(250) group = QtWidgets.QGroupBox('Polymer Type Distribution', self.view) self.indicatorbox = QtWidgets.QVBoxLayout() self.indicatorbox.setContentsMargins(5,5,5,5) group.setLayout(self.indicatorbox) hbox = QtWidgets.QHBoxLayout() hbox.addWidget(group) self.view.setLayout(hbox) self.setWidgetResizable(True) self.setWidget(self.view) self.setAlignment(QtCore.Qt.AlignHCenter) def updateTypes(self, types): print("Updating polymer type view", flush=True) for i in range(self.indicatorbox.count()): self.indicatorbox.takeAt(0) numtotal = sum([num for num, text, color in types]) def getIndexFunction(index): return lambda : self.indexClicked.emit(index) for index, entry in enumerate(types): num, text, color = entry print("num, text, color:", num, text, color, flush=True) pi = ParticleIndicator(num, numtotal, color, text) self.indicatorbox.addWidget(pi) pi.clicked.connect(getIndexFunction(index)) self.indicatorbox.addStretch() self.view.update() No newline at end of file