def plot(self, x, y, *args, **kwargs): # set up infinity line and get its position self.plotItem.plot(x, y, *args, **kwargs) self.addItem(self.line) x_val = self.line.value() if x_val == 0: y_val = 0 else: idx = val2ind(x_val, self.wavenumbers) x_val = self.wavenumbers[idx] y_val = y[idx] if not self._meanSpec: txt_html = f'<div style="text-align: center"><span style="color: #FFF; font-size: 12pt">\ Spectrum #{self.spectrumInd}</div>' else: txt_html = f'<div style="text-align: center"><span style="color: #FFF; font-size: 12pt">\ {self._mean_title}</div>' txt_html += f'<div style="text-align: center"><span style="color: #FFF; font-size: 12pt">\ X = {x_val: .2f}, Y = {y_val: .4f}</div>' self.txt = TextItem(html=txt_html, anchor=(0, 0)) ymax = max(y) self._y = y self.txt.setPos(1500, 0.95 * ymax) self.addItem(self.txt)
def __init__(self, size, width=5, brush=None, pen=None, suffix='m', offset=None): GraphicsObject.__init__(self) GraphicsWidgetAnchor.__init__(self) self.setFlag(self.ItemHasNoContents) self.setAcceptedMouseButtons(QtCore.Qt.NoButton) if brush is None: brush = getConfigOption('foreground') self.brush = fn.mkBrush(brush) self.pen = fn.mkPen(pen) self._width = width self.size = size if offset == None: offset = (0, 0) self.offset = offset self.bar = QtGui.QGraphicsRectItem() self.bar.setPen(self.pen) self.bar.setBrush(self.brush) self.bar.setParentItem(self) self.text = TextItem(text=fn.siFormat(size, suffix=suffix), anchor=(0.5, 1), angle=90, color=(0, 0, 0)) self.text.setParentItem(self)
def __init__(self, linePos=650, txtPosRatio=0.35, invertX=True, *args, **kwargs): """ A widget to display a 1D spectrum :param linePos: the initial position of the InfiniteLine :param txtPosRatio: a coefficient that determines the relative position of the textItem :param invertX: whether to invert X-axis """ super(SpectraPlotWidget, self).__init__(*args, **kwargs) self._data = None assert (txtPosRatio >= 0) and (txtPosRatio <= 1), 'Please set txtPosRatio value between 0 and 1.' self.txtPosRatio = txtPosRatio self.positionmap = dict() self.wavenumbers = None self._meanSpec = True # whether current spectrum is a mean spectrum self.line = InfiniteLine(movable=True) self.line.setPen((255, 255, 0, 200)) self.line.setValue(linePos) self.line.sigPositionChanged.connect(self.sigEnergyChanged) self.line.sigPositionChanged.connect(self.getEnergy) self.addItem(self.line) self.cross = PlotDataItem([linePos], [0], symbolBrush=(255, 0, 0), symbolPen=(255, 0, 0), symbol='+', symbolSize=20) self.cross.setZValue(100) self.addItem(self.cross) self.txt = TextItem() self.getViewBox().invertX(invertX) self.spectrumInd = 0 self.selectedPixels = None self._y = None
def update(self): self.p4.clear() self.p4_2.clear() self.value_declaration() self.vlim = 1 / pow(1 + sqrt(glo_var.l), 2) self.trans_point = self.trans_func(glo_var.alpha) self.betas_pre = np.linspace(0, self.trans_point - 0.000001, 20) # # explain here in the meeting # self.betas_to_add_pre = np.array([self.trans_point-0.000001]) # self.betas_to_add_post = np.array([self.trans_point+0.000001]) # self.betas_pre = np.concatenate((self.betas_pre_pre[:-1],self.betas_to_add_pre)) self.betas_post = np.array([self.trans_point + 0.000001, 1]) # self.domain = np.concatenate((self.betas_pre,self.betas_post)) self.j_r_values = np.array([ i * (self.lambda_1 - i) / (self.lambda_1 + (glo_var.l - 1) * i) for i in self.betas_pre ]) self.rho_avg_pre = [] self.rho_avg_post = [] for i in self.betas_pre: self.rho_avg_pre += [self.cal_rho(self.js(glo_var.alpha, i))] for i in self.betas_post: self.rho_avg_post += [self.cal_rho(self.js(glo_var.alpha, i))] if self.betacheck == 1: self.text = TextItem( html= '<span style="color: #1034A6; font-size: 16pt;">\u03b2</span></div>', anchor=(0.5, 1.5)) self.p4.addItem(self.text) self.arrow = ArrowItem(pos=(glo_var.beta, 0), angle=-90) self.p4.addItem(self.arrow) self.betacheck = 0 self.text.setPos(glo_var.beta, 0) self.arrow.setPos(glo_var.beta, 0) # minused 0.00000001 since it is not working self.p4.plot(self.betas_pre, self.j_r_values, pen=self.jpen) # Can alpha_star be 0? then I need to add conner case if glo_var.alpha >= glo_var.alpha_star: self.jpost = self.j_c else: self.jpost = self.j_l self.p4.plot([self.trans_point, 1], [self.jpost, self.jpost], pen=self.jpen) self.trans_line = self.p4.plot([self.trans_point, self.trans_point], [0, 1], pen=self.dash) self.make_right_axis() self.set_range()
def __init__(self): super(baselinePlotWidget, self).__init__() self.line.setValue(800) self.txt = TextItem('', anchor=(0, 0)) self.cross = PlotDataItem([800], [0], symbolBrush=(255, 255, 0), symbolPen=(255, 255, 0), symbol='+',symbolSize=20) self.line.sigPositionChanged.connect(self.getMu) self._mu = None
def setTexts(self, text): for i in self.textItems: i.scene().removeItem(i) self.textItems = [] for t in text: item = TextItem(t) self.textItems.append(item) item.setParentItem(self)
def update(self, x, y, colors, cutpoint_x=None, selection_limit=None, names=None): """ Function replots a graph. Parameters ---------- x : np.ndarray One-dimensional array with X coordinates of the points y : array-like List of np.ndarrays that contains an array of Y values for each sequence. colors : array-like List of Qt colors (eg. Qt.red) for each sequence. cutpoint_x : int, optional A starting cutpoint - the location of the vertical line. selection_limit : tuple The tuple of two values that limit the range for selection. names : array-like The name of each sequence that shows in the legend, if None legend is not shown. legend_anchor : array-like The anchor of the legend in the graph """ self.clear_plot() if names is None: names = [None] * len(y) self.sequences = y self.x = x self.selection_limit = selection_limit self.data_increasing = [np.sum(d[1:] - d[:-1]) > 0 for d in y] # plot sequence for s, c, n, inc in zip(y, colors, names, self.data_increasing): c = QColor(c) self.plot(x, s, pen=mkPen(c, width=2), antialias=True) if n is not None: label = TextItem(text=n, anchor=(0, 1), color=QColor(0, 0, 0, 128)) label.setPos(x[-1], s[-1]) self._set_anchor(label, len(x) - 1, inc) self.addItem(label) self._plot_cutpoint(cutpoint_x) self.autoRange()
class PreviewWidget(GraphicsLayoutWidget): def __init__(self): super(PreviewWidget, self).__init__() self.setMinimumHeight(250) self.setMinimumWidth(250) self.view = self.addViewBox(lockAspect=True, enableMenu=False) self.imageitem = ImageItem() self.textitem = TextItem(anchor=(0.5, 0)) self.textitem.setFont(QFont("Zero Threes")) self.imgdata = None self.imageitem.setOpts(axisOrder="row-major") self.view.addItem(self.imageitem) self.view.addItem(self.textitem) self.textitem.hide() self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) # def textItemBounds(axis, frac=1.0, orthoRange=None): # b = self.textitem.boundingRect() # sx, sy = self.view.viewPixelSize() # x, y = sx*b.width(), sy*b.height() # if axis == 0: return (-x/2, x/2) # if axis == 1: return (0, y) # # self.textitem.dataBounds = textItemBounds def sizeHint(self): return QSize(250, 250) def preview_header(self, header: NonDBHeader): try: data = header.meta_array()[0] self.setImage(data) except IndexError: self.imageitem.clear() self.setText("UNKNOWN DATA FORMAT") def setImage(self, imgdata): self.imageitem.clear() self.textitem.hide() self.imgdata = imgdata self.imageitem.setImage(np.log(self.imgdata * (self.imgdata > 0) + (self.imgdata < 1)), autoLevels=True) self.imageitem.setTransform( QTransform(1, 0, 0, -1, 0, self.imgdata.shape[-2])) self.view.autoRange() def setText(self, text): self.textitem.setText(text) self.imageitem.clear() self.textitem.setVisible(True) self.view.autoRange()
def calcPartitionNamePlacement(self, label: pg.TextItem, index: int, emit_signal=False): start_point = self.segments[index].getXPos() end_point = self.segments[index + 1].getXPos() mid_point = start_point + ((end_point - start_point) / 2) label.setPos(mid_point, self.vertical_placement) label.updateTextPos() if emit_signal: self.item.updatePartitionValuePosition.emit(index, mid_point)
def annotate_curve(self, pv_name): curve = self.chart.findCurve(pv_name) if curve: annot = TextItem( html= '<div style="text-align: center"><span style="color: #FFF;">This is the' '</span><br><span style="color: #FF0; font-size: 16pt;">PEAK</span></div>', anchor=(-0.3, 0.5), border='w', fill=(0, 0, 255, 100)) annot = TextItem("test", anchor=(-0.3, 0.5)) self.chart.annotateCurve(curve, annot)
def __init__(self, *args, **kwargs): PlotWidget.__init__(self, *args, **kwargs) self.fit_range_marker = InfiniteLine(movable=True, pen=mkPen('w', width=2)) self.text_no_data = TextItem('Press "Analyze" to display results', anchor=(0.5, 0.5)) self._log_mode = False self.showGrid(x=True, y=True) self.addItem(self.fit_range_marker) self.addItem(self.text_no_data) self.reset() self.fit_range_marker.sigPositionChangeFinished.connect( self.sigFitRangeChanged.emit)
class ModelFitWidget(PlotWidget): sigFitRangeChanged = pyqtSignal() def __init__(self, *args, **kwargs): PlotWidget.__init__(self, *args, **kwargs) self.fit_range_marker = InfiniteLine(movable=True, pen=mkPen('w', width=2)) self.text_no_data = TextItem('Press "Analyze" to display results', anchor=(0.5, 0.5)) self._log_mode = False self.showGrid(x=True, y=True) self.addItem(self.fit_range_marker) self.addItem(self.text_no_data) self.reset() self.fit_range_marker.sigPositionChangeFinished.connect( self.sigFitRangeChanged.emit) def reset(self): self.getPlotItem().setXRange(-1.0, 1.0) self.getPlotItem().setYRange(-1.0, 1.0) self.text_no_data.setVisible(True) self.fit_range_marker.setVisible(False) self.fit_range_marker.setPos(0.0) def setup(self): self.text_no_data.setVisible(False) self.fit_range_marker.setVisible(True) def get_range(self): if self._log_mode: return np.power(10.0, self.fit_range_marker.pos().x()) else: return self.fit_range_marker.pos().x() def set_range(self, new_range: float): self._update_range_marker(new_range) def set_log(self, value: bool): fit_range = self.get_range() self._log_mode = value self.setLogMode(self._log_mode, False) self._update_range_marker(fit_range) def _update_range_marker(self, marker_pos): if self._log_mode: if marker_pos <= 0.0: marker_pos = 1.0 self.fit_range_marker.setPos(np.log10(marker_pos)) else: self.fit_range_marker.setPos(marker_pos) self.sigFitRangeChanged.emit()
def __init__(self): super(PreviewWidget, self).__init__() self.setMinimumHeight(250) self.setMinimumWidth(250) self.view = self.addViewBox(lockAspect=True, enableMenu=False) self.imageitem = ImageItem() self.textitem = TextItem(anchor=(0.5, 0)) self.textitem.setFont(QFont('Zero Threes')) self.imgdata = None self.view.addItem(self.imageitem) self.view.addItem(self.textitem) self.textitem.hide() self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
def addPlotAera(self): plotname = 'Plot' + str(len(self.lPlotWindows) + 1) axis = self.TimeAxisItem(orientation='bottom') vb = ViewBox() newdataPlot = PlotWidget(self, viewBox=vb, axisItems={'bottom': axis}, name = plotname) self.dataPlotLayout.addWidget(newdataPlot) self.configPlotArea(newdataPlot) newdataPlot.plotItem.scene().sigMouseClicked.connect(self.mouseClick) newdataPlot.plotItem.scene().sigMouseMoved.connect(self.mouseMove) ## drag and drop # newdataPlot.dragEnterEvent = self.dragEnterEvent # newdataPlot.plotItem.setAcceptDrops(True) # newdataPlot.plotItem.dropEvent = self.dropEvent # set the default plot range newdataPlot.setXRange(self.minTimestamp,self.maxTimestamp,padding=20) newdataPlot.setYRange(-10, 10, padding=20) newdataPlot.plotItem.getAxis('left').setWidth(w=30) newdataPlot.plotItem.hideButtons() newdataPlot.installEventFilter(self) newdataPlot.plotItem.showGrid(True, True, 0.5) vb.scaleBy(y=None) # make it the current selection plot area self.currSelctPlotWgt.setBackground('default') self.currSelctPlotWgt = newdataPlot # set the current selection to plot1 self.currSelctPlotWgt.setBackground(0.95) # link x axis to view box of the first data plot viewBox = self.dataPlot.plotItem.vb # reference to viewbox of the plot 1 axis.linkToView(viewBox) #axis.linkToView(vb) # Link plot 1 X axia to the view box lastplotItem = self.dataPlotLayout.itemAt(self.dataPlotLayout.count()-2).widget() lastplotItem.getViewBox().setXLink(newdataPlot) #lastplotItem.getViewBox().autoRange() txtY_value = TextItem("", fill=(0, 0, 255, 80), anchor=(0, 1), color='w') txtY_value.setParentItem(newdataPlot.plotItem.getViewBox()) self.autoRangeAllWins() self.lPlotWindows.append(plotname)
def __init__(self, x: list, y: list, graphics_view: PlotWidget, labels: str, units=None, x_labels=None, width=0.4): """ Constructor / Instantiation of class Parameters ---------- x : list x-values y : list y-values graphics_view : PlotWidget widget to add items labels : str legend labels units : tuple measurement units for tuple width : int, float width of any bars x_labels : array-like array of dates, i.e. time-period """ super().__init__() Assertor.assert_data_types([x, y, graphics_view, labels, units, x_labels, width], [list, list, PlotWidget, str, (type(None), tuple), (type(None), list), (float, int)]) self.x = asarray(arange(1, len(x) + 1, 1)) self.y = asarray([float(val.replace(" ", "").replace("%", "")) if val else 0 for val in y]) self.graphics_view = graphics_view self.labels = labels self.units = units if units else tuple(["" for _ in range(10)]) self.x_time = x_labels self.width = width self.bar_item_1 = BarGraphItem(x=self.x, height=self.y, width=self.width, brush="#a8ccec") self.graphics_view.addItem(self.bar_item_1) self.bar_item_2 = None self.label = TextItem() pen = mkPen(color="#4c96d7", style=Qt.SolidLine, width=1) self.vertical_line = InfiniteLine(angle=90, movable=False, pen=pen) self.graphics_view.addItem(self.vertical_line) self.view_box = self.graphics_view.getViewBox() self.configure_cross_hair() self.graphics_view.plotItem.vb.setLimits(xMin=0, xMax=max(self.x) + 1) self.graphics_view.setMenuEnabled(False)
def cleanPlot(self): self.plot.clear() self.text["avg"] = TextItem('', color=(200, 200, 250), anchor=(0, 1)) self.text["std"] = TextItem('', color=(200, 200, 250), anchor=(0, 1)) self.text["slope"] = TextItem('', color=(200, 200, 250), anchor=(0, 1)) self.text["corr"] = TextItem('', color=(200, 200, 250), anchor=(0, 1)) plotLabels = [ self.text["avg"], self.text["std"], self.text["slope"], self.text["corr"] ] for plotLabel in plotLabels: self.plot.addItem(plotLabel)
def __init__(self, viewBox, el_net): self.arrows = [] self.arrow_labels = [] self.line_flows = relative_line_load(el_net) for l in self.line_flows: arrow = ArrowItem(angle = l['angle'], tipAngle = 40, headLen= 10, tailLen=0, pen={'color': 'w', 'width': 1}, brush = 'y', pxMode = True) arrow.setPos(*l['pos']) arrow_label = TextItem("{0:.0f}%".format(l['rel_load'])) arrow_label.setPos(*l['pos']) viewBox.addItem(arrow) viewBox.addItem(arrow_label) self.arrows.append(arrow) self.arrow_labels.append(arrow_label)
def __init__(self, *args, **kwargs): super(MapViewWidget, self).__init__(*args, **kwargs) # self.scene.sigMouseMoved.connect(self.showSpectra) self.scene.sigMouseClicked.connect(self.showSpectra) self.view.invertY(True) # add arrow self.cross = PlotDataItem([0], [0], symbolBrush=(200, 0, 0), symbolPen=(200, 0, 0), symbol='+', symbolSize=16) self.view.addItem(self.cross) self.cross.hide() #add txt self.txt = TextItem('', anchor=(0, 0)) self.addItem(self.txt)
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()
class FilteratorImageView(ImageView): def __init__(self, parent=None): super().__init__(parent=parent) self.ui.histogram.hide() self.ui.roiBtn.hide() self.ui.menuBtn.hide() self.image_view_text = TextItem(text="", color=(255, 0, 0), anchor=(0, 0)) self.getView().addItem(self.image_view_text) self.image_view_vline = InfiniteLine(angle=90, movable=False) self.image_view_hline = InfiniteLine(angle=0, movable=False) self.getView().addItem(self.image_view_vline, ignoreBounds=True) self.getView().addItem(self.image_view_hline, ignoreBounds=True) self.image_view_proxy = SignalProxy( self.getView().scene().sigMouseMoved, rateLimit=60, slot=self.onMouseMoved) self.signals = FilteratorImageViewSignals() def setProcessed(self, status=True): if status == True: self.image_view_text.setText("") else: self.image_view_text.setText("Not processed!", color=(255, 0, 0)) def onMouseMoved(self, event): pos = event[0] item = self.getImageItem() viewbox = self.getView() if item.sceneBoundingRect().contains(pos): mouse_point = viewbox.mapSceneToView(pos) self.image_view_vline.setPos(mouse_point.x()) self.image_view_hline.setPos(mouse_point.y()) self.signals.mouse_pos_updated.emit( (mouse_point.x(), mouse_point.y()))
def __init__(self, *args, **kwargs): super(MapViewWidget, self).__init__(*args, **kwargs) # self.scene.sigMouseMoved.connect(self.showSpectra) self.scene.sigMouseClicked.connect(self.showSpectra) self.view.invertY(True) # add arrow # self.arrow = ArrowItem(angle=60, headLen=15, tipAngle=45, baseAngle=30, brush = (200, 80, 20)) # self.arrow.setPos(0, 0) self.cross = PlotDataItem([0], [0], symbolBrush=(200, 0, 0), symbolPen=(200, 0, 0), symbol='+', symbolSize=16) self.view.addItem(self.cross) self.cross.hide() #add txt self.txt = TextItem('', anchor=(0, 0)) self.addItem(self.txt)
def _plot_horizontal_lines(self): """ Function plots the vertical dashed lines that points to the selected sequence values at the y axis. """ for _ in range(len(self.sequences)): self.plot_horline.append( PlotCurveItem(pen=mkPen(QColor(Qt.blue), style=Qt.DashLine))) self.plot_horlabel.append( TextItem(color=QColor(Qt.black), anchor=(0, 1))) for item in self.plot_horlabel + self.plot_horline: self.addItem(item)
def plot(self, x, y, *args, **kwargs): # set up infinity line and get its position plot_item = self.plotItem.plot(x, y, *args, **kwargs) self.addItem(self.line) self.addItem(self.cross) x_val = self.line.value() idx = val2ind(x_val, x) x_val = x[idx] y_val = y[idx] txt_html = toHtml(f'X = {x_val: .2f}, Y = {y_val: .4f}') self.txt = TextItem(html=txt_html, anchor=(0, 0)) self.txt.setZValue(self.zmax - 1) self.cross.setData([x_val], [y_val]) self.cross.setZValue(self.zmax) ymax = np.max(y) if ymax > self.ymax: self.ymax = ymax self._x, self._y = x, y r = self.txtPosRatio self.txt.setPos(r * x[-1] + (1 - r) * x[0], self.ymax) return plot_item
def _createLabels(self, points, viewbox, logMode): for x, y in points: # fill the text xtext = self._getXText(x) ytext = self._getYText(y) text_item = TextItem() text_item.setHtml(("<div style='{}'> " + "<span><b>x=</b>{} " + "<span><b>y=</b>{}</span> " + "</div>").format( self._label_style, xtext, ytext)) # add text_item in the right position (take into account log mode) if logMode[0]: x = numpy.log10(x) if logMode[1]: y = numpy.log10(y) text_item.setPos(x, y) self._labels.append(text_item) viewbox.addItem(text_item, ignoreBounds=True) # Add "highlight" marker at each point highlight = PlotDataItem( numpy.array(points), pen=None, symbol="s", symbolBrush="35393C88", pxMode=True, symbolSize=self.trigger_point_size, ) # set log mode highlight.setLogMode(*logMode) # hack to make the CurvesPropertiesTool ignore the highlight points highlight._UImodifiable = False # Add it to the vbox and keep a reference viewbox.addItem(highlight, ignoreBounds=True) self._highlights.append(highlight)
def createIntersectionPoint(self): # TODO self.plotLength = self.model.projectData("length") * LENGTH_COEFFICIENT # create the horizontal plant line green = QColor(0, 144, 54) plantPen = pyqtgraph.mkPen(width=2, color=green) # Hochschule für Forstwirtschaft Rottenburg self.plantLine = InfiniteLine(self.model.projectData("count"), 0, plantPen, True) self.plantLine.sigPositionChanged.connect(self.updateCount) self.controlWidget.setCount(self.model.projectData("count")) self.controlWidget.countChanged.connect(self.plantLine.setValue) self.plantLabel = TextItem(html="<b><font color='" + green.name() + "'>Pflanzenzahl</font></b>", anchor=(-0.15, 0.9)) self.plantLabel.setParentItem(self.plantLine) self.plotWidget.addPlotItem(self.plantLine) # create the vertical fence line red = QColor(255, 0, 0) fencePen = pyqtgraph.mkPen(width=2, color=red) self.fenceLine = InfiniteLine(self.model.projectData("length"), 90, fencePen, True) self.fenceLine.sigPositionChanged.connect(self.updateLength) self.fenceLine.sigPositionChangeFinished.connect(self.updatePlotLength) self.controlWidget.setLength(self.model.projectData("length")) self.controlWidget.lengthChanged.connect(self.fenceLine.setValue) self.fenceLabel = TextItem(html="<b><font color='" + red.name() + "'>Zaunlänge</font></b>", anchor=(-2.5, 0.9), angle=-90) self.fenceLabel.setParentItem(self.fenceLine) self.plotWidget.addPlotItem(self.fenceLine) # create an arrow item as point of intersection self.arrowItem = ArrowItem(angle=-45, tipAngle=30, baseAngle=20, headLen=20, tailLen=None, pen={"color" : "#333", "width" : 2}, brush=QColor(255, 123, 0)) self.arrowItem.setPos(self.model.projectData("length"), self.model.projectData("count")) self.plotWidget.addPlotItem(self.arrowItem)
def __init__(self, parent=None): super().__init__(parent=parent) self.ui.histogram.hide() self.ui.roiBtn.hide() self.ui.menuBtn.hide() self.image_view_text = TextItem(text="", color=(255, 0, 0), anchor=(0, 0)) self.getView().addItem(self.image_view_text) self.image_view_vline = InfiniteLine(angle=90, movable=False) self.image_view_hline = InfiniteLine(angle=0, movable=False) self.getView().addItem(self.image_view_vline, ignoreBounds=True) self.getView().addItem(self.image_view_hline, ignoreBounds=True) self.image_view_proxy = SignalProxy( self.getView().scene().sigMouseMoved, rateLimit=60, slot=self.onMouseMoved) self.signals = FilteratorImageViewSignals()
def _plot_horizontal_lines(self): """ Function plots the vertical dashed lines that points to the selected sequence values at the y axis. """ highlight = self.palette().highlight() text = self.palette().text() for _ in range(len(self.sequences)): self.plot_horline.append( PlotCurveItem(pen=mkPen(highlight.color(), style=Qt.DashLine))) self.plot_horlabel.append( TextItem(color=text.color(), anchor=(0, 1))) for item in self.plot_horlabel + self.plot_horline: self.addItem(item)
def setData(self, **kwds): self.data = kwds if 'pos' in self.data: for n in range(kwds['pos'].shape[0]): text_item = TextItem(kwds['text'][n]) text_pos = (kwds['pos'][n][0], kwds['pos'][n][1]) text_item.setPos(*kwds['pos'][n]) text_item.setParentItem(self) self.text = kwds.pop('text', []) GraphItem.setData(self, **self.data)
def __init__(self): self.lastKey = None QtWidgets.QWidget.__init__(self) self.resize(1200, 800) #self.showFullScreen() self.layout = QtWidgets.QGridLayout() self.setLayout(self.layout) self.view = GraphicsLayoutWidget() self.layout.addWidget(self.view, 0, 0, 1, 2) self.label = QtWidgets.QLabel() self.layout.addWidget(self.label, 1, 0, 1, 2) self.label.setWordWrap(True) font = QtGui.QFont("monospace", 14, QtGui.QFont.Weight.Bold) self.label.setFont(font) self.passBtn = QtWidgets.QPushButton('Pass') self.failBtn = QtWidgets.QPushButton('Fail') self.layout.addWidget(self.passBtn, 2, 0) self.layout.addWidget(self.failBtn, 2, 1) self.passBtn.clicked.connect(self.passTest) self.failBtn.clicked.connect(self.failTest) self.views = (self.view.addViewBox(row=0, col=0), self.view.addViewBox(row=0, col=1), self.view.addViewBox(row=0, col=2)) labelText = ['test output', 'standard', 'diff'] for i, v in enumerate(self.views): v.setAspectLocked(1) v.invertY() v.image = ImageItem(axisOrder='row-major') v.image.setAutoDownsample(True) v.addItem(v.image) v.label = TextItem(labelText[i]) v.setBackgroundColor(0.5) self.views[1].setXLink(self.views[0]) self.views[1].setYLink(self.views[0]) self.views[2].setXLink(self.views[0]) self.views[2].setYLink(self.views[0])
def _createLabels(self, points): for x, y in points: # create label at x,y _x = self._getXValue(x) _y = self._getYValue(y) text_item = TextItem() text_item.setPos(x, y) text_item.setHtml(("<div style='{}'> " + "<span><b>x=</b>{} " + "<span><b>y=</b>{}</span> " + "</div>").format( self._label_style, _x, _y)) self._labels.append(text_item) self._plot_item.addItem(text_item, ignoreBounds=True) # Add "highlight" marker at each point self._highlights.setData(pos=points)
def __init__(self, plots): """ Constructor arguments: - plots: the plots returns: the initialized class """ self.plots = plots self.cursor_x = [None] * 3 self.cursor_y = [None] * 3 self.cursor_label = [None] * 3 self.signal_proxy = [None] * 3 self.plot_data_items = [None] * 3 self._x = [None] * 3 self._y = [None] * 3 for num, plot in enumerate(plots): self.cursor_x[num] = InfiniteLine(angle=90, movable=False) self.cursor_y[num] = InfiniteLine(angle=0, movable=False) plot.addItem(self.cursor_x[num], ignoreBounds=True) plot.addItem(self.cursor_y[num], ignoreBounds=True) self.signal_proxy[num] = SignalProxy(plot.scene().sigMouseMoved, rateLimit=60, slot=self.update_cursor) self.cursor_label[num] = TextItem('', (255, 255, 255), anchor=(0, 0)) self.cursor_label[num].setPos(-10.4, 10) plot.addItem(self.cursor_label[num]) # Find the PlotDataItem displaying data for item in plot.getPlotItem().items: if isinstance(item, PlotDataItem): self.plot_data_items[num] = item self.hide_cursors()
def setTexts(self, text): """ Generates the text (number) associated with each test point :param text: the numbers of all test points """ for i in self.textItems: try: i.scene().removeItem(i) except Exception as e: pass self.textItems = [] for t in text: item = TextItem(t) item.setColor([255, 255, 255]) self.textItems.append(item) item.setParentItem(self)
class VariantPlotWidget(QWidget): """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. """ AREA = 0 LINE = 1 curvePlotted = pyqtSignal(QModelIndex) plotReady = pyqtSignal() cleared = pyqtSignal() def __init__(self): super().__init__() # the plot widget is always # disabled at the first start self.setDisabled(True) ### TESTING ### self.model = None self.selectionModel = None self.view = 0 self.calc = False self.plotLength = 0 self.plotCount = 0 self.fenceLine = None self.plantLine = None self.arrowItem = None #self.lengthCoefficient = 1.5 # in model festlegen! #self.transparency = 0.3 ### TESTING ### self.controlWidget = PlotControlWidget() self.plotWidget = NaturalPlotView() layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.controlWidget) layout.addWidget(self.plotWidget) self.setLayout(layout) # connect signals self.controlWidget.chartViewChanged.connect(self.updateChartView) self.controlWidget.countEnabled.connect(self.setPlantLineVisible) self.controlWidget.lengthEnabled.connect(self.setFenceLineVisible) def retranslateUi(self): # update the control widget self.controlWidget.retranslateUi() # translate the plot widget self.plotWidget.retranslateUi() def setModel(self, model): self.model = model self.model.dataChanged.connect(self.update) self.model.modelReset.connect(self.update) # das muss optimiert werden, weil dies private Signale sind # es dient dazu, dass gelöschte, oder veränderte (verschobene) Zeilen # nicht mehr ausgewählt werden können (selectionModel) self.model.rowsRemoved.connect(self.modelRemoveAction) self.model.rowsMoved.connect(self.modelRemoveAction) self.model.calculated.connect(self.calculate) def calculate(self): self.calc = True self.paintCalculation() def updateChartView(self, index): self.view = index # update calculation # möglicherweise sollte hier paintEvent() verwendet werden?! # # vorher muss hier noch eine Berechnung stattfinden if self.calc: self.paintCalculation() def setSelectionModel(self, selectionModel): # setup view's selectionModel self.selectionModel = selectionModel def modelRemoveAction(self): # TODO # wird benötigt, da sonst Fehler, wenn mit Enter bestätigt in Zaunlänge self.setDisabled(True) self.clear() def clear(self): # disconnect signals if isinstance(self.plantLine, InfiniteLine): self.plantLine.disconnect() self.plantLine = None if isinstance(self.fenceLine, InfiniteLine): self.fenceLine.disconnect() self.fenceLine = None self.plotWidget.clear() self.cleared.emit() def paintCalculation(self): if not self.calc: return # search for enabeld items # items contains at least one parent and one child # remove parents from children items = self.model.match(self.model.index(0, 0), TreeModel.StatusRole, True, -1, Qt.MatchRecursive) children = [item for item in items if item.parent().isValid()] if self.view == self.AREA: self.plotAreaChart(children) elif self.view == self.LINE: self.plotLineChart(children) def createIntersectionPoint(self): # TODO self.plotLength = self.model.projectData("length") * LENGTH_COEFFICIENT # create the horizontal plant line green = QColor(0, 144, 54) plantPen = pyqtgraph.mkPen(width=2, color=green) # Hochschule für Forstwirtschaft Rottenburg self.plantLine = InfiniteLine(self.model.projectData("count"), 0, plantPen, True) self.plantLine.sigPositionChanged.connect(self.updateCount) self.controlWidget.setCount(self.model.projectData("count")) self.controlWidget.countChanged.connect(self.plantLine.setValue) self.plantLabel = TextItem(html="<b><font color='" + green.name() + "'>Pflanzenzahl</font></b>", anchor=(-0.15, 0.9)) self.plantLabel.setParentItem(self.plantLine) self.plotWidget.addPlotItem(self.plantLine) # create the vertical fence line red = QColor(255, 0, 0) fencePen = pyqtgraph.mkPen(width=2, color=red) self.fenceLine = InfiniteLine(self.model.projectData("length"), 90, fencePen, True) self.fenceLine.sigPositionChanged.connect(self.updateLength) self.fenceLine.sigPositionChangeFinished.connect(self.updatePlotLength) self.controlWidget.setLength(self.model.projectData("length")) self.controlWidget.lengthChanged.connect(self.fenceLine.setValue) self.fenceLabel = TextItem(html="<b><font color='" + red.name() + "'>Zaunlänge</font></b>", anchor=(-2.5, 0.9), angle=-90) self.fenceLabel.setParentItem(self.fenceLine) self.plotWidget.addPlotItem(self.fenceLine) # create an arrow item as point of intersection self.arrowItem = ArrowItem(angle=-45, tipAngle=30, baseAngle=20, headLen=20, tailLen=None, pen={"color" : "#333", "width" : 2}, brush=QColor(255, 123, 0)) self.arrowItem.setPos(self.model.projectData("length"), self.model.projectData("count")) self.plotWidget.addPlotItem(self.arrowItem) def plotAreaChart(self, children): # check parents and children # the lists must contain only one item if not len(children) == 1: warning = QMessageBox(self) warning.setWindowModality(Qt.WindowModal) # check for mac only warning.setIcon(QMessageBox.Warning) warning.setStandardButtons(QMessageBox.Ok) warning.setWindowTitle(QApplication.translate("VariantPlotWidget", "Wuchshüllenrechner")) warning.setText("<b>" + QApplication.translate("VariantPlotWidget", "Too many variants are enabled!") + "</b>") warning.setInformativeText(QApplication.translate("VariantPlotWidget", "The area view allows you to set only one variant enabled " "at the same time. Please select the variant manually or " "choose the line view.")) warning.exec() return False (index,) = children # clear the plot widget self.clear() # plot the curve curve = EnhancedCurveItem(index, True) self.plotWidget.addPlotItem(curve) self.curvePlotted.emit(index) # create point of intersection self.createIntersectionPoint() # add the description to the view self.setEnabled(True) self.plotWidget.showDescription() self.plotReady.emit() def plotLineChart(self, children): # check parents and children # the lists must contain only one item if len(children) == 0: print("Fehler") return False # clear the plot widget self.clear() for child in children: # plot the curve curve = EnhancedCurveItem(child) self.plotWidget.addPlotItem(curve) self.curvePlotted.emit(child) # create point of intersection self.createIntersectionPoint() # add the description to the view self.setEnabled(True) self.plotWidget.showDescription() self.plotReady.emit() def updatePlotLength(self): length = self.fenceLine.value() hint = False # update the chart, if necessary if length >= self.plotLength: self.paintCalculation() hint = True elif length < self.plotLength / 5: self.paintCalculation() hint = True if hint: # notice the user about the update notice = QMessageBox(self) notice.setWindowModality(Qt.WindowModal) # check for mac only notice.setIcon(QMessageBox.Information) notice.setStandardButtons(QMessageBox.Ok) notice.setWindowTitle(QApplication.translate("VariantPlotWidget", "Wuchshüllenrechner")) notice.setText("<b>" + QApplication.translate("VariantPlotWidget", "Die Skalierung wurde verändert!") + "</b>") notice.setInformativeText(QApplication.translate("VariantPlotWidget", "Da sich die Zaunlänge geändert hat, wurde die Skalierung " "des Diagramms ebenfalls verändert.")) notice.exec() def updateCount(self, line): # save the new value in the model and # update the control widget count = int(self.plantLine.value()) self.model.setProjectData("count", count) self.controlWidget.setCount(count) # change the arrow item self.arrowItem.setPos(self.model.projectData("length"), self.model.projectData("count")) # update the legend self.plotReady.emit() def updateLength(self, line): # save the new value in the model and # update the control widget length = int(self.fenceLine.value()) self.model.setProjectData("length", length) self.controlWidget.setLength(length) # change the arrow item self.arrowItem.setPos(self.model.projectData("length"), self.model.projectData("count")) # update the legend self.plotReady.emit() def setPlantLineVisible(self, state): # check, if plant line is not None to avoid errors if not self.plantLine: return False self.plantLine.setVisible(state) def setFenceLineVisible(self, state): # check, if plant line is not None to avoid errors if not self.fenceLine: return False self.fenceLine.setVisible(state)
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)