Source code for pymodaq_gui.plotting.data_viewers.viewer1Dbasic

from qtpy import QtGui, QtWidgets
from qtpy.QtCore import Slot, QObject, QThread, Signal, QLocale, QDateTime, QSize
import sys
import pyqtgraph as pg
import numpy as np

from pymodaq_utils.logger import set_logger, get_module_name
from pymodaq_utils import utils

logger = set_logger(get_module_name(__file__))


[docs] class Viewer1DBasic(QObject): """this plots 1D data on a plotwidget. one linear region to select data, one infinite line to select point """ roi_region_signal = Signal(tuple) roi_line_signal = Signal(float) def __init__(self, parent=None, show_region=False, show_line=False): """ Parameters ---------- parent Attributes ---------- parent: (QWidget) roi_region: (pyqtgraph LinerrRegionItem) roi_line: (pyqtgraph InfiniteLine graphitem) Properties ---------- labels: (list of str) x_axis: (Axis or dict) """ super().__init__() if parent is None: parent = QtWidgets.QWidget() parent.show() self.parent = parent self.plot_colors = utils.plot_colors self.data_to_export = None self.datas = None self._x_axis = None self.labels = [] self.plot_channels = None self.legend = None self.setup_ui() self.show_roi_region(show_region) self.show_roi_line(show_line)
[docs] def show(self, state=True): self.parent.setVisible(state)
[docs] def setup_ui(self): vboxlayout = QtWidgets.QVBoxLayout() self.plotwidget = pg.PlotWidget() self.parent.setLayout(vboxlayout) vboxlayout.addWidget(self.plotwidget) vboxlayout.setContentsMargins(0, 0, 0, 0) self.legend = self.plotwidget.addLegend() self.roi_region = pg.LinearRegionItem() self.roi_line = pg.InfiniteLine(movable=True) self.plotwidget.plotItem.addItem(self.roi_region) self.plotwidget.plotItem.addItem(self.roi_line) self.roi_region.sigRegionChanged.connect(self.update_region) self.roi_line.sigPositionChanged.connect(self.update_line)
[docs] def get_line_position(self): return self.roi_line.getXPos()
[docs] def show_roi_region(self, show=True): self.roi_region.setVisible(show)
[docs] def show_roi_line(self, show=True): self.roi_line.setVisible(show)
[docs] def update_region(self, item): self.roi_region_signal.emit(item.getRegion())
[docs] def update_line(self, item): self.roi_line_signal.emit(item.getPos()[0])
@property def labels(self): return self._labels @labels.setter def labels(self, labels): self._labels = labels self.update_labels(labels)
[docs] def update_labels(self, labels=[]): try: if self.datas is not None: labels_tmp = labels[:] if self.labels == labels: if self.labels == [] or len(self.labels) < len(self.datas): self._labels = ["CH{}".format(ind) for ind in range(len(self.datas))] else: flag = True while flag: items = [item[1].text for item in self.legend.items] if len(items) == 0: flag = False else: self.legend.removeItem(items[0]) if len(labels) < len(self.plot_channels): for ind in range(len(labels), len(self.plot_channels)): labels_tmp.append('CH{:02d}'.format(ind)) if len(labels_tmp) == len(self.plot_channels): for ind, channel in enumerate(self.plot_channels): self.legend.addItem(channel, labels_tmp[ind]) self._labels = labels_tmp except Exception as e: logger.exception(str(e))
[docs] @Slot(list) def show_data(self, datas): if datas is not None and datas[0] is not None: self.datas = datas if self.labels == [] or len(self.labels) != len(datas): self.update_labels(self.labels) if self.plot_channels is None: # initialize data and plots self.ini_data_plots(len(datas)) elif len(self.plot_channels) != len(datas): self.remove_plots() self.ini_data_plots(len(datas)) for ind_plot, data in enumerate(datas): if self._x_axis is None or len(self._x_axis) != len(data): self._x_axis = np.linspace(0, len(data), len(data), endpoint=False) self.plot_channels[ind_plot].setData(x=self.x_axis, y=data)
[docs] def ini_data_plots(self, Nplots): self.plot_channels = [] channels = [] for ind in range(Nplots): channel = self.plotwidget.plot() channel.setPen(self.plot_colors[ind]) self.legend.addItem(channel, self._labels[ind]) channels.append(ind) self.plot_channels.append(channel)
[docs] def remove_plots(self): if self.plot_channels is not None: for channel in self.plot_channels: self.plotwidget.removeItem(channel) self.plot_channels = None if self.legend is not None: items = [item[1].text for item in self.legend.items] for item in items: self.legend.removeItem(item)
[docs] def set_axis_label(self, axis_settings=dict(orientation='bottom', label='x axis', units='pxls')): axis = self.plotwidget.plotItem.getAxis(axis_settings['orientation']) axis.setLabel(text=axis_settings['label'], units=axis_settings['units'])
@property def x_axis(self): return self._x_axis @x_axis.setter def x_axis(self, x_axis): label = 'Pxls' units = '' if isinstance(x_axis, dict): if 'data' in x_axis: xdata = x_axis['data'] if 'label' in x_axis: label = x_axis['label'] if 'units' in x_axis: units = x_axis['units'] else: xdata = x_axis self._x_axis = xdata self.show_data(self.datas) self.set_axis_label(dict(orientation='bottom', label=label, units=units))
if __name__ == '__main__': # pragma: no cover app = QtWidgets.QApplication(sys.argv) def print_region(xx): print(xx) def print_line(x): print(x) Form = QtWidgets.QWidget() prog = Viewer1DBasic(Form) # prog.show_roi_region() prog.show_roi_line() prog.roi_region_signal.connect(print_region) prog.roi_line_signal.connect(print_line) from pymodaq.utils.daq_utils import gauss1D x = np.linspace(0, 200, 201) y1 = gauss1D(x, 75, 25) y2 = gauss1D(x, 120, 50, 2) tau_half = 27 tau2 = 100 x0 = 50 dx = 20 ydata_expodec = np.zeros((len(x))) ydata_expodec[:50] = 1 * gauss1D(x[:50], x0, dx, 2) ydata_expodec[50:] = 1 * np.exp(-(x[50:] - x0) / (tau_half / np.log(2))) # +1*np.exp(-(x[50:]-x0)/tau2) ydata_expodec += 0.1 * np.random.rand(len(x)) prog.show_data([y1, y2, ydata_expodec]) Form.show() prog.x_axis prog.update_labels(labels=['sig0', 'tralala', 'ouhaouh']) sys.exit(app.exec_())