def updateDisplay(self): self._plot.title = self.titleString() if self.subTitleString(): self._plot.subTitle = self.subTitleString() self._plot.xlabel = self.xaxisName() self._plot.ylabel = self.yaxisName() if self.normalized: self._plot.ylabel += " (norm: %s)" % self.normalized self.plotcurves = [] self.addAllCurves() if self.timeaxis: self._plot.viewport = (.1, .85, .18, .88) self._axes.setXtickCallback(self.xtickCallBack) self._plot.offsetXLabel = -.08 scale = self.yaxisScale() if scale: axes = self._plot.getAxes(0) curwin = axes.getWindow() if not curwin: curwin = [0, 1, scale[0], scale[1]] curves = axes.getCurves() xmins = [] xmaxs = [] for c in curves: if c.visible: xmins.append(min(c.x)) xmaxs.append(max(c.x)) if xmins and xmaxs: curwin[0] = min(xmins) curwin[1] = max(xmaxs) axes.setWindow(curwin[0], curwin[1], scale[0], scale[1]) InteractiveGRWidget.update(self)
def pointsAdded(self, series): plotcurve = self.series2curve[series] plotcurve.x = series.x plotcurve.y = series.y plotcurve.legend = series.title self._axes.addCurves(plotcurve) InteractiveGRWidget.update(self)
def initUi(self): # axes setup self.widget = InteractiveGRWidget(self) self.plot = Plot(viewport=(.1, .95, .25, .95)) self.axes = NicosTimePlotAxes(self.plot._viewport) self.axes.setWindow(0, 1, 0, 1) self.plot.addAxes(self.axes) self.plot.setLegend(True) self.plot.setLegendWidth(0.07) self.plot.offsetXLabel = -.2 self.axes.setXtickCallback(self.xtickCallBack) self.widget.addPlot(self.plot) layout = QHBoxLayout(self) layout.addWidget(self.widget) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.curves = [] # event support self.widget.cbm.addHandler(LegendEvent.ROI_CLICKED, self.on_legendItemClicked, LegendEvent) self.widget.cbm.addHandler(MouseEvent.MOUSE_MOVE, self.on_mouseMove) self.timeSeriesUpdate.connect(self.on_timeSeriesUpdate)
def __init__(self, parent, window, timeaxis=False): InteractiveGRWidget.__init__(self, parent) NicosPlot.__init__(self, window, timeaxis=timeaxis) self.timeaxis = timeaxis or (self.axescls == NicosTimePlotAxes) self.leftTurnedLegend = True self.statusMessage = None self.mouselocation = None self._cursor = self.cursor() self._mouseSelEnabled = self.getMouseSelectionEnabled() self._markertype = gr.MARKERTYPE_OMARK dictPrintType = dict(gr.PRINT_TYPE) for prtype in [gr.PRINT_JPEG, gr.PRINT_TIF]: dictPrintType.pop(prtype) self._saveTypes = (";;".join(dictPrintType.values()) + ";;" + ";;".join(gr.GRAPHIC_TYPE.values())) self._saveName = None self._color = ColorIndexGenerator() self._plot = Plot(viewport=(.1, .85, .15, .88)) self._plot.setLegendWidth(0.05) self._axes = self.axescls(viewport=self._plot.viewport) self._axes.backgroundColor = 0 self._plot.addAxes(self._axes) self._plot.title = self.titleString() self.addPlot(self._plot) guiConn = GUIConnector(self) guiConn.connect(LegendEvent.ROI_CLICKED, self.on_legendItemClicked, LegendEvent) guiConn.connect(ROIEvent.ROI_CLICKED, self.on_roiItemClicked, ROIEvent) guiConn.connect(MouseEvent.MOUSE_PRESS, self.on_fitPicker_selected) guiConn.connect(MouseEvent.MOUSE_MOVE, self.on_mouseMove) self.logXinDomain.connect(self.on_logXinDomain) self.logYinDomain.connect(self.on_logYinDomain) self.setLegend(True) self.updateDisplay()
def __init__(self, widget, **kwds): InteractiveGRWidget.__init__(self, widget, **kwds) self.widget = widget self.adjustSelectRect = self._noadjustSelectRect
class TrendPlot(NicosWidget, QWidget): designer_description = 'A trend plotter for one or more devices' designer_icon = ':/plotter' widgetInfo = pyqtSignal(str) timeSeriesUpdate = pyqtSignal(object) # colors = [Qt.red, Qt.darkGreen, Qt.blue, Qt.black, Qt.magenta, Qt.cyan, # Qt.darkGray] devices = PropDef( 'devices', 'QStringList', [], ''' List of devices or cache keys that the plot should display. For devices use device name. For keys use cache key with "." or "/" separator, e.g. T.heaterpower. To access items of a sequence, use subscript notation, e.g. T.userlimits[0] ''') names = PropDef( 'names', 'QStringList', [], 'Names for the plot curves, ' 'defaults to the device names/keys.') legend = PropDef('legend', bool, False, 'If a legend should be shown.') plotwindow = PropDef( 'plotwindow', int, 3600, 'The range of time in ' 'seconds that should be represented by the plot.') plotinterval = PropDef( 'plotinterval', float, 2, 'The minimum time in ' 'seconds between two points that should be ' 'plotted.') height = PropDef( 'height', int, 10, 'Height of the plot widget in units ' 'of app font character width.') width = PropDef( 'width', int, 30, 'Width of the plot widget in units ' 'of app font character width.') # pylint: disable=W0231 def __init__(self, parent, designMode=False): self.ncurves = 0 self.ctimers = {} self.keyindices = {} self.plotcurves = {} self.series = {} self.legendobj = None # X label settings, default values for default window of 3600s self._showdate = False self._showsecs = False QWidget.__init__(self, parent) NicosWidget.__init__(self) def initUi(self): # axes setup self.widget = InteractiveGRWidget(self) self.plot = Plot(viewport=(.1, .95, .25, .95)) self.axes = NicosTimePlotAxes(self.plot._viewport) self.axes.setWindow(0, 1, 0, 1) self.plot.addAxes(self.axes) self.plot.setLegend(True) self.plot.setLegendWidth(0.07) self.plot.offsetXLabel = -.2 self.axes.setXtickCallback(self.xtickCallBack) self.widget.addPlot(self.plot) layout = QHBoxLayout(self) layout.addWidget(self.widget) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.curves = [] # event support self.widget.cbm.addHandler(LegendEvent.ROI_CLICKED, self.on_legendItemClicked, LegendEvent) self.widget.cbm.addHandler(MouseEvent.MOUSE_MOVE, self.on_mouseMove) self.timeSeriesUpdate.connect(self.on_timeSeriesUpdate) def xtickCallBack(self, x, y, _svalue, value): gr.setcharup(-1., 1.) gr.settextalign(gr.TEXT_HALIGN_RIGHT, gr.TEXT_VALIGN_TOP) dx = .02 timeVal = localtime(value) if self._showdate: gr.text(x + dx, y - 0.01, strftime(DATEFMT, timeVal)) if self._showsecs: gr.text(x - dx, y - 0.01, strftime(TIMEFMT, timeVal)) else: gr.text(x - dx, y - 0.01, strftime(SHORTTIMEFMT, timeVal)) gr.setcharup(0., 1.) def propertyUpdated(self, pname, value): if pname == 'plotwindow': self._showdate = value > 24 * 3600 self._showsecs = value < 300 elif pname in ('width', 'height'): self.setMinimumSize( QSize(self._scale * (self.props['width'] + .5), self._scale * (self.props['height'] + .5))) elif pname == 'legend': self.plot.setLegend(value) NicosWidget.propertyUpdated(self, pname, value) def setFont(self, font): pass # TODO: can't set font for GR right now def on_mouseMove(self, event): wc = event.getWC(self.plot.viewport) ts = strftime(DATEFMT + ' ' + TIMEFMT, localtime(wc.x)) msg = 't = %s, y = %g' % (ts, wc.y) self.widgetInfo.emit(msg) def on_legendItemClicked(self, event): if event.getButtons() & MouseEvent.LEFT_BUTTON: event.curve.visible = not event.curve.visible self.update() def on_timeSeriesUpdate(self, series): curve = self.plotcurves[series] curve.x = series.x curve.y = series.y c = self.axes.getCurves() dy = abs(c.ymin - c.ymax) * 0.05 self.axes.setWindow(c.xmin, c.xmax, c.ymin - dy, c.ymax + dy) self.widget.update() self.ctimers[curve].start(5000) def on_keyChange(self, key, value, time, expired): if key not in self.keyindices or value is None: return for index in self.keyindices[key]: series = self.series[key, index] # restrict time of value to 1 minute past at # maximum, so that it doesn't get culled by the windowing time = max(time, currenttime() - 60) if index: try: fvalue = functools.reduce(operator.getitem, index, value) series.add_value(time, fvalue) except Exception: pass else: series.add_value(time, value) def addcurve(self, key, index, title, scale, offset): series = TimeSeries(key, self.props['plotinterval'], scale, offset, self.props['plotwindow'], self) series.init_empty() curve = PlotCurve([currenttime()], [0], legend=title) self.plotcurves[series] = curve self.ncurves += 1 self.curves.append(curve) self.axes.addCurves(curve) self.series[key, index] = series self.widget.update() # record the current value at least every 5 seconds, to avoid curves # not updating if the value doesn't change def update(): series.synthesize_value() self.ctimers[curve] = QTimer(singleShot=True) self.ctimers[curve].timeout.connect(update) def registerKeys(self): for key, name in zip_longest(self.props['devices'], self.props['names']): if name is None: name = key key, index, scale, offset = extractKeyAndIndex(key) keyid = self._source.register(self, key) self.keyindices.setdefault(keyid, []).append(index) self.addcurve(keyid, index, name, scale, offset)