diff --git a/artiq/applets/plot_xy.py b/artiq/applets/plot_xy.py index da7f2197d..8eaf9786a 100755 --- a/artiq/applets/plot_xy.py +++ b/artiq/applets/plot_xy.py @@ -2,6 +2,7 @@ import numpy as np import PyQt5 # make sure pyqtgraph imports Qt5 +from PyQt5.QtCore import QTimer import pyqtgraph from artiq.applets.simple import TitleApplet @@ -11,6 +12,12 @@ class XYPlot(pyqtgraph.PlotWidget): def __init__(self, args): pyqtgraph.PlotWidget.__init__(self) self.args = args + self.timer = QTimer() + self.timer.setSingleShot(True) + self.timer.timeout.connect(self.length_warning) + self.mismatch = {'X values': False, + 'Error bars': False, + 'Fit values': False} def data_changed(self, data, mods, title): try: @@ -24,17 +31,29 @@ class XYPlot(pyqtgraph.PlotWidget): fit = data.get(self.args.fit, (False, None))[1] if not len(y) or len(y) != len(x): - return + self.mismatch['X values'] = True + else: + self.mismatch['X values'] = False if error is not None and hasattr(error, "__len__"): if not len(error): error = None elif len(error) != len(y): - return + self.mismatch['Error bars'] = True + else: + self.mismatch['Error bars'] = False if fit is not None: if not len(fit): fit = None elif len(fit) != len(y): - return + self.mismatch['Fit values'] = True + else: + self.mismatch['Fit values'] = False + if not any(self.mismatch.values()): + self.timer.stop() + else: + if not self.timer.isActive(): + self.timer.start(1000) + return self.clear() self.plot(x, y, pen=None, symbol="x") @@ -50,6 +69,13 @@ class XYPlot(pyqtgraph.PlotWidget): xi = np.argsort(x) self.plot(x[xi], fit[xi]) + def length_warning(self): + self.clear() + text = "⚠️ dataset lengths mismatch:\n" + errors = ', '.join([k for k, v in self.mismatch.items() if v]) + text = ' '.join([errors, "should have the same length as Y values"]) + self.addItem(pyqtgraph.TextItem(text)) + def main(): applet = TitleApplet(XYPlot)