From 81a86b2b043401f7d036364e9aedf9d7b584e34b Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Wed, 13 Jan 2016 06:53:23 -0700 Subject: [PATCH] applets/plot_xy_hist: do not clear arrow/histogram when unrelated data is modified --- artiq/applets/plot_xy_hist.py | 64 +++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/artiq/applets/plot_xy_hist.py b/artiq/applets/plot_xy_hist.py index b74dd724d..8f31615e1 100755 --- a/artiq/applets/plot_xy_hist.py +++ b/artiq/applets/plot_xy_hist.py @@ -6,6 +6,17 @@ import pyqtgraph from artiq.applets.simple import SimpleApplet +def _compute_ys(histogram_bins, histograms_counts): + bin_centers = np.empty(len(histogram_bins)-1) + for i in range(len(bin_centers)): + bin_centers[i] = (histogram_bins[i] + histogram_bins[i+1])/2 + + ys = np.empty(histograms_counts.shape[0]) + for n, counts in enumerate(histograms_counts): + ys[n] = sum(bin_centers*counts)/sum(counts) + return ys + + class XYHistPlot(pyqtgraph.GraphicsWindow): def __init__(self, args): pyqtgraph.GraphicsWindow.__init__(self, title="XY/Histogram") @@ -15,6 +26,7 @@ class XYHistPlot(pyqtgraph.GraphicsWindow): self.xy_plot = self.addPlot() self.xy_plot_data = None self.arrow = None + self.selected_index = None self.hist_plot = self.addPlot() self.hist_plot_data = None @@ -27,28 +39,36 @@ class XYHistPlot(pyqtgraph.GraphicsWindow): self.xy_plot_data = None self.hist_plot_data = None self.arrow = None + self.selected_index = None self.histogram_bins = histogram_bins - bin_centers = np.empty(len(histogram_bins)-1) - for i in range(len(bin_centers)): - bin_centers[i] = (histogram_bins[i] + histogram_bins[i+1])/2 - - ys = np.empty_like(xs) - for n, counts in enumerate(histograms_counts): - ys[n] = sum(bin_centers*counts)/sum(counts) + ys = _compute_ys(self.histogram_bins, histograms_counts) self.xy_plot_data = self.xy_plot.plot(x=xs, y=ys, pen=None, symbol="x", symbolSize=20) self.xy_plot_data.sigPointsClicked.connect(self._point_clicked) - for point, counts in zip(self.xy_plot_data.scatter.points(), - histograms_counts): + for index, (point, counts) in ( + enumerate(zip(self.xy_plot_data.scatter.points(), + histograms_counts))): + point.histogram_index = index point.histogram_counts = counts self.hist_plot_data = self.hist_plot.plot( stepMode=True, fillLevel=0, brush=(0, 0, 255, 150)) + def _set_partial_data(self, xs, histograms_counts): + ys = _compute_ys(self.histogram_bins, histograms_counts) + self.xy_plot_data.setData(x=xs, y=ys, + pen=None, + symbol="x", symbolSize=20) + for index, (point, counts) in ( + enumerate(zip(self.xy_plot_data.scatter.points(), + histograms_counts))): + point.histogram_index = index + point.histogram_counts = counts + def _point_clicked(self, data_item, spot_items): spot_item = spot_items[0] position = spot_item.pos() @@ -61,14 +81,38 @@ class XYHistPlot(pyqtgraph.GraphicsWindow): self.xy_plot.addItem(self.arrow) else: self.arrow.setPos(position) + self.selected_index = spot_item.histogram_index self.hist_plot_data.setData(x=self.histogram_bins, y=spot_item.histogram_counts) + def _can_use_partial(self, mods): + if self.hist_plot_data is None: + return False + for mod in mods: + if mod["action"] != "setitem": + return False + if mod["path"] == [self.args.xs, 1]: + if mod["key"] == self.selected_index: + return False + elif mod["path"][:2] == [self.args.histograms_counts, 1]: + if len(mod["path"]) > 2: + index = mod["path"][2] + else: + index = mod["key"] + if index == self.selected_index: + return False + else: + return False + return True + def data_changed(self, data, mods): xs = data[self.args.xs][1] histogram_bins = data[self.args.histogram_bins][1] histograms_counts = data[self.args.histograms_counts][1] - self._set_full_data(xs, histogram_bins, histograms_counts) + if self._can_use_partial(mods): + self._set_partial_data(xs, histograms_counts) + else: + self._set_full_data(xs, histogram_bins, histograms_counts) def main():