class SweepDataPlot(GraphicsView): GREEN = [0, 204, 153] BLUE = [100, 171, 246] RED = [221, 61, 53] PURPLE = [175, 122, 197] ASH = [52, 73, 94] GRAY = [178, 186, 187] COLORS = [BLUE, RED, GREEN, PURPLE, ASH, GRAY] if sys.platform == 'darwin': LW = 3 else: LW = 1.5 def __init__(self): GraphicsView.__init__(self) # create layout self.layout = pg.GraphicsLayout() self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setSpacing(-1.) self.setBackground(None) self.setCentralItem(self.layout) # create axes and apply formatting axisItems = dict() for pos in ['bottom', 'left', 'top', 'right']: axisItems[pos] = AxisItem(orientation=pos, maxTickLength=-7) self.p = PlotItem(axisItems=axisItems) self.setTitle('Sweep data', fontScaling=1.3, color='k') self.layout.addItem(self.p) self.p.vb.setBackgroundColor('w') self.p.setContentsMargins(10, 10, 10, 10) for pos in ['bottom', 'left', 'top', 'right']: ax = self.p.getAxis(pos) ax.setZValue(0) # draw on top of patch ax.setVisible(True) # make all axes visible ax.setPen(width=self.LW * 2 / 3, color=0.5) # grey spines and ticks try: ax.setTextPen('k') # black text except AttributeError: pass ax.setStyle(autoExpandTextSpace=True, tickTextOffset=4) self.p.getAxis('top').setTicks([]) self.p.getAxis('top').setHeight(0) self.p.getAxis('right').setTicks([]) self.x_axis = self.p.getAxis('bottom') self.y_axis = self.p.getAxis('left') self.x_axis.setLabel('Voltage', units='V', color='k', size='12pt') self.y_axis.setLabel('Current', units='A', color='k', size='12pt') self.y_axis.setStyle(tickTextWidth=35) # set auto range and mouse panning / zooming self.p.enableAutoRange(x=True, y=True) self.p.setLimits(xMin=-1e20, xMax=1e20, yMin=-1e20, yMax=1e20) def suggestPadding(axis): length = self.p.vb.width() if axis == 0 else self.p.vb.height() if length > 0: if axis == 0: padding = 0 else: padding = np.clip(1. / (length**0.5), 0.02, 0.1) else: padding = 0.02 return padding self.p.vb.suggestPadding = suggestPadding # set default ranges to start self.p.setXRange(-10, 10) self.p.setYRange(-10, 10) # add legend self.legend = LegendItem(brush=fn.mkBrush(255, 255, 255, 150), labelTextColor='k', offset=(20, -20)) self.legend.setParentItem(self.p.vb) def clear(self): self.p.clear() # clear current plot self.legend.clear() # clear current legend def plot(self, sweep_data): self.clear() xdata = sweep_data.get_column(0) xdata_title = sweep_data.titles[0] ydata = sweep_data.values()[1:] # format plot according to sweep type unit = xdata_title.unit if xdata_title.has_unit() else 'a.u.' self.x_axis.setLabel(xdata_title.name, unit=unit) self.y_axis.setLabel('Current', unit='A') if sweep_data.params['sweep_type'] == 'transfer': self.setTitle('Transfer curve') self.p.setLogMode(x=False, y=True) self.legend.setOffset((20, -20)) # legend in bottom-left corner ydata = [np.abs(y) for y in ydata] elif sweep_data.params['sweep_type'] == 'output': self.setTitle('Output curve') self.p.setLogMode(x=False, y=False) self.legend.setOffset((-20, 20)) # legend in top-right corner ydata = [np.abs(y) for y in ydata] else: self.setTitle('Sweep curve') self.p.setLogMode(x=False, y=False) ydata = [np.abs(y) for y in ydata] # plot data self.lines = [] for y, c in zip(ydata, itertools.cycle(self.COLORS)): p = self.p.plot(xdata, y, pen=fn.mkPen(color=c, width=self.LW)) self.lines.append(p) # add legend for l, t in zip(self.lines, sweep_data.column_names[1:]): self.legend.addItem(l, str(t)) self.p.autoRange() def setTitle(self, text, fontScaling=None, color=None, font=None): # work around pyqtplot which forces the title to be HTML if text is None: self.p.setTitle(None) # clears title and hides title column else: self.p.setTitle( '') # makes title column visible, sets placeholder text self.p.titleLabel.item.setPlainText( text) # replace HTML with plain text if color is not None: color = fn.mkColor(color) self.p.titleLabel.item.setDefaultTextColor(color) if font is not None: self.p.titleLabel.item.setFont(font) if fontScaling is not None: font = self.p.titleLabel.item.font() defaultFontSize = QtWidgets.QLabel('test').font().pointSize() fontSize = round(defaultFontSize * fontScaling, 1) font.setPointSize(fontSize) self.p.titleLabel.item.setFont(font)
class NaturalPlotView(GraphicsView): """Creates a simple about dialog. The about dialog contains general information about the application and shows the copyright notice. That's why the class has no attributes or return values. """ def __init__(self): super().__init__() # settings self.setBackground("#fff") self.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken) self.setAntialiasing(True) # create custom view box view_box = ViewBox() view_box.setMouseEnabled(False, False) view_box.setLimits(xMin=0, yMin=0, minXRange=10, minYRange=100) view_box.setRange(xRange=(0, 400), yRange=(0, 5000)) view_box.enableAutoRange() # create natural axis items self.x_axis = NaturalAxis("bottom") self.x_axis.setLabel(QApplication.translate("NaturalPlotView", "Fence length"), "m") self.y_axis = NaturalAxis("left") self.y_axis.setLabel(QApplication.translate("NaturalPlotView", "Number of plants")) # create fence information text self.fenceItem = TextItem(border=pyqtgraph.mkPen(width=2, color="#555"), fill=pyqtgraph.mkBrush((255, 255, 255, 200))) # create tube information text self.tubeItem = TextItem(border=pyqtgraph.mkPen(width=2, color="#555"), fill=pyqtgraph.mkBrush((255, 255, 255, 200)), anchor=(1,1)) # create plot item with custom view box and natural axis items self.plotItem = PlotItem(viewBox=view_box, axisItems={"bottom" : self.x_axis, "left" : self.y_axis}, enableMenu=False) self.plotItem.setContentsMargins(5, 5, 12, 5) self.plotItem.hideButtons() self.plotItem.hide() self.setCentralWidget(self.plotItem) # connect actions view_box.sigResized.connect(self.updateTubeLegendPosition) # translate the plot item self.retranslateUi() def retranslateUi(self): # title label titleStyle = "color: #111; font-size: 15px; font-weight: bold" titleLabel = "<span style='{style}'>{title}</span>".format(style=titleStyle, title="Ergebnis: Funktion(en) der Kostengleichheit") self.plotItem.setTitle(titleLabel) # axis items #self.x_axis.setLabel(QApplication.translate("NaturalPlotView", "Fence length"), "m") #self.y_axis.setLabel(QApplication.translate("NaturalPlotView", "Number of plants")) # fence hint self.fenceItem.setHtml("<p style='margin: 0; color: #555'><b>" + QApplication.translate("NaturalPlotView", "Pfeil über Funktion(en):") + "</b> " + QApplication.translate("NaturalPlotView", "Zaun günstiger") + "</p>") # tube hint self.tubeItem.setHtml("<p style='margin: 0; color: #555'><b>" + QApplication.translate("NaturalPlotView", "Pfeil unter Funktion(en):") + "</b> " + QApplication.translate("NaturalPlotView", "Wuchshülle günstiger") + "</p>") def addPlotItem(self, item, *args, **kwargs): # first show the plot item if not self.plotItem.isVisible(): self.plotItem.show() self.plotItem.addItem(item, *args, **kwargs) def removePlotItem(self, item): self.plotItem.removeItem(item) #TODO: def clear(self): self.plotItem.hide() self.plotItem.clear() def showDescription(self): viewBox = self.plotItem.getViewBox() self.fenceItem.setPos(15, 10) self.fenceItem.setParentItem(viewBox) rect = viewBox.screenGeometry() self.tubeItem.setPos(rect.width() - 15, rect.height() - 10) self.tubeItem.setParentItem(viewBox) def updateTubeLegendPosition(self): rect = self.plotItem.getViewBox().screenGeometry() self.tubeItem.setPos(rect.width() - 15, rect.height() - 10) def export(self, gfxfile): exporter = TestImageExporter(self.plotItem) exporter.parameters()["width"] = 2007.0 # 17 cm / 300 DPI # export the graphics to the selected file exporter.export(gfxfile)