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

new type histogram view in particle analysis

parent 48dddf1d
...@@ -30,7 +30,7 @@ from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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)
......
...@@ -19,7 +19,7 @@ along with this program, see COPYING. ...@@ -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): ...@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment