Commit 04b35ae2 authored by Lars Bittrich's avatar Lars Bittrich
Browse files

new type histogram view in particle analysis

parent 48dddf1d
Loading
Loading
Loading
Loading
+22 −77
Original line number Original line Diff line number Diff line
@@ -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
@@ -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()
@@ -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')
@@ -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()
    
    
@@ -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)
@@ -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:
@@ -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)
+72 −2
Original line number Original line Diff line number Diff line
@@ -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
@@ -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