Loading analysis/analysisview.py +22 −77 Original line number 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.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar from .analysiswidgets import ExpExcelDialog, AdditiveViewer from .analysiswidgets import ExpExcelDialog, AdditiveViewer, ParticleTypeView from .loadresults import LoadWITecResults from .particleeditor import ParticleEditor from .database import DataBaseWindow Loading Loading @@ -67,11 +67,10 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.currentSpectrumIndex = 0 self.lastSpectrumInFocus = None self.typeHistogramCanvas = FigureCanvas(Figure()) self.typeHistogram = ParticleTypeView(self) self.typeHistogram.indexClicked.connect(self.getAdditivePlot) self.sizeHistogramCanvas = FigureCanvas(Figure()) self.typeHist_ax = self.typeHistogramCanvas.figure.subplots() self.typeHist_ax.axis('off') sizeHistGroup = QtWidgets.QGroupBox() sizeHistLayout = QtWidgets.QHBoxLayout() self.sizeHist_ax = self.sizeHistogramCanvas.figure.subplots() Loading Loading @@ -107,7 +106,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): splitter1.addWidget(sizeHistGroup) splitter2 = QtWidgets.QSplitter(QtCore.Qt.Horizontal) splitter2.addWidget(splitter1) splitter2.addWidget(self.typeHistogramCanvas) splitter2.addWidget(self.typeHistogram) splitter2.setSizes([300, 150]) 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.exec() def getAdditivePlot(self, event): clickedindex = int(np.round(event.xdata)) @QtCore.pyqtSlot(int) def getAdditivePlot(self, clickedindex): 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.show() Loading Loading @@ -419,10 +419,6 @@ class ParticleAnalysis(QtWidgets.QMainWindow): 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) if sqlEnabled: self.expSQLAct.setDisabled(False) Loading Loading @@ -568,37 +564,15 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.updateSpecPlot() 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 colorList = [] if self.selOverlayAct.isChecked(): abundancyList = [] for index, checkbox in enumerate(self.polymerCheckBoxes): 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 labelList = [] for index, i in enumerate(self.datastats.typehistogram): 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: numads = '' else: Loading @@ -609,46 +583,17 @@ class ParticleAnalysis(QtWidgets.QMainWindow): numads = '(' + str(numads) + ')' numpolymers = i[1] label = ('{} x ' + self.datastats.typehistogram[index][0] + ' {}').format(numpolymers, numads) x_label_position = self.typeHist_ax.get_xlim()[1]*0.05 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) labelList.append(label) 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 self.sizeHist_ax.clear() self.sizeHist_ax.axis('on') 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) sizehist = np.histogram(self.sizes, self.bins) Loading analysis/analysiswidgets.py +72 −2 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ along with this program, see COPYING. If not, see <https://www.gnu.org/licenses/>. """ from PyQt5 import QtWidgets from PyQt5 import QtWidgets, QtGui, QtCore import numpy as np import pandas as pd import os Loading Loading @@ -202,3 +202,73 @@ class AdditiveViewer(QtWidgets.QWidget): self.ax.hist(sortedAdditives) self.ax.set_ylabel('Number', fontsize = 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 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.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar from .analysiswidgets import ExpExcelDialog, AdditiveViewer from .analysiswidgets import ExpExcelDialog, AdditiveViewer, ParticleTypeView from .loadresults import LoadWITecResults from .particleeditor import ParticleEditor from .database import DataBaseWindow Loading Loading @@ -67,11 +67,10 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.currentSpectrumIndex = 0 self.lastSpectrumInFocus = None self.typeHistogramCanvas = FigureCanvas(Figure()) self.typeHistogram = ParticleTypeView(self) self.typeHistogram.indexClicked.connect(self.getAdditivePlot) self.sizeHistogramCanvas = FigureCanvas(Figure()) self.typeHist_ax = self.typeHistogramCanvas.figure.subplots() self.typeHist_ax.axis('off') sizeHistGroup = QtWidgets.QGroupBox() sizeHistLayout = QtWidgets.QHBoxLayout() self.sizeHist_ax = self.sizeHistogramCanvas.figure.subplots() Loading Loading @@ -107,7 +106,7 @@ class ParticleAnalysis(QtWidgets.QMainWindow): splitter1.addWidget(sizeHistGroup) splitter2 = QtWidgets.QSplitter(QtCore.Qt.Horizontal) splitter2.addWidget(splitter1) splitter2.addWidget(self.typeHistogramCanvas) splitter2.addWidget(self.typeHistogram) splitter2.setSizes([300, 150]) 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.exec() def getAdditivePlot(self, event): clickedindex = int(np.round(event.xdata)) @QtCore.pyqtSlot(int) def getAdditivePlot(self, clickedindex): 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.show() Loading Loading @@ -419,10 +419,6 @@ class ParticleAnalysis(QtWidgets.QMainWindow): 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) if sqlEnabled: self.expSQLAct.setDisabled(False) Loading Loading @@ -568,37 +564,15 @@ class ParticleAnalysis(QtWidgets.QMainWindow): self.updateSpecPlot() 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 colorList = [] if self.selOverlayAct.isChecked(): abundancyList = [] for index, checkbox in enumerate(self.polymerCheckBoxes): 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 labelList = [] for index, i in enumerate(self.datastats.typehistogram): 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: numads = '' else: Loading @@ -609,46 +583,17 @@ class ParticleAnalysis(QtWidgets.QMainWindow): numads = '(' + str(numads) + ')' numpolymers = i[1] label = ('{} x ' + self.datastats.typehistogram[index][0] + ' {}').format(numpolymers, numads) x_label_position = self.typeHist_ax.get_xlim()[1]*0.05 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) labelList.append(label) 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 self.sizeHist_ax.clear() self.sizeHist_ax.axis('on') 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) sizehist = np.histogram(self.sizes, self.bins) Loading
analysis/analysiswidgets.py +72 −2 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ along with this program, see COPYING. If not, see <https://www.gnu.org/licenses/>. """ from PyQt5 import QtWidgets from PyQt5 import QtWidgets, QtGui, QtCore import numpy as np import pandas as pd import os Loading Loading @@ -202,3 +202,73 @@ class AdditiveViewer(QtWidgets.QWidget): self.ax.hist(sortedAdditives) self.ax.set_ylabel('Number', fontsize = 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