Source code for pylablib.aux_libs.gui.widgets.line_plotter

"""
Simple PyQtGraph-based line plotter.

A small expansion on top of :class:`.pyqtgraph.PlotWidget` which allows for thread-safe plot updating.
"""

import pyqtgraph


[docs]class LinePlotter(pyqtgraph.PlotWidget): """ Line plotter object. Built on top of :class:`.pyqtgraph.PlotWidget` class. Args: parent: parent widget """ def __init__(self, parent=None): super(LinePlotter, self).__init__(parent) self.data={} self._traces={} self.trace_names=[] self.updated=True self.addLegend() self.setLabel("left","Signal") self.showGrid(True,True,0.7)
[docs] def add_trace(self, name, caption=None, *args, **kwargs): """ Add a trace plot. If caption is not ``None``, the trace is also added into the legend under the given caption. All other arguments are passed to the underlying :meth:`.pyqtgraph.PlotWidget.plot` method. """ if name in self._traces: raise ValueError("trace {} already exists".format(name)) if caption is not None: kwargs["name"]=caption line=self.plot([],[],*args,**kwargs) self._traces[name]=(line,caption) self.trace_names.append(name)
[docs] def delete_trace(self, name): """Delete trace plot""" line,caption=self._traces.pop(name) self.trace_names.remove(name) self.removeItem(line) if caption is not None: self.plotItem.legend.removeItem(caption)
[docs] def set_traces(self, data, hide_missing=True): """ Set data to be plotted. `data` is a list or a dictionary of 2-column numpy arrays containing x- and y-coordinates of the plots. If it is a list, the columns are assumed to be in the order of their creation (also available as ``trace_names`` attribute). If it is a dictionary, the keys are the column names. If ``hide_missing==True`` and some traces are missing from the data, hide them (although they still appear in the legend); otherwise, the missing traces are left unchanged. This function is thread-safe (i.e., the application state remains consistent if it's called from another thread, although race conditions on simultaneous calls from multiple threads still might happen). """ if isinstance(data,list): self.data=dict(zip(self.trace_names,data)) else: self.data=data.copy() if hide_missing: for n in self.trace_names: if n not in self.data: self.data[n]=[] self.updated=True
[docs] def update_traces(self, only_new_data=True): """ Update displayed traces. If ``only_new_data==True`` and the data hasn't changed since the last call to ``update_traces``, skip replotting. """ if (not only_new_data) or self.updated: self.updated=False for n in self.trace_names: if n in self.data: t=self.data[n] if len(t): self._traces[n][0].setData(t[:,0],t[:,1]) else: self._traces[n][0].setData([],[])