applets/plot_xy_hist: do not clear arrow/histogram when unrelated data is modified

This commit is contained in:
Sebastien Bourdeauducq 2016-01-13 06:53:23 -07:00
parent e37e0bdc1c
commit 81a86b2b04
1 changed files with 54 additions and 10 deletions

View File

@ -6,6 +6,17 @@ import pyqtgraph
from artiq.applets.simple import SimpleApplet 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): class XYHistPlot(pyqtgraph.GraphicsWindow):
def __init__(self, args): def __init__(self, args):
pyqtgraph.GraphicsWindow.__init__(self, title="XY/Histogram") pyqtgraph.GraphicsWindow.__init__(self, title="XY/Histogram")
@ -15,6 +26,7 @@ class XYHistPlot(pyqtgraph.GraphicsWindow):
self.xy_plot = self.addPlot() self.xy_plot = self.addPlot()
self.xy_plot_data = None self.xy_plot_data = None
self.arrow = None self.arrow = None
self.selected_index = None
self.hist_plot = self.addPlot() self.hist_plot = self.addPlot()
self.hist_plot_data = None self.hist_plot_data = None
@ -27,28 +39,36 @@ class XYHistPlot(pyqtgraph.GraphicsWindow):
self.xy_plot_data = None self.xy_plot_data = None
self.hist_plot_data = None self.hist_plot_data = None
self.arrow = None self.arrow = None
self.selected_index = None
self.histogram_bins = histogram_bins 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, self.xy_plot_data = self.xy_plot.plot(x=xs, y=ys,
pen=None, pen=None,
symbol="x", symbolSize=20) symbol="x", symbolSize=20)
self.xy_plot_data.sigPointsClicked.connect(self._point_clicked) self.xy_plot_data.sigPointsClicked.connect(self._point_clicked)
for point, counts in zip(self.xy_plot_data.scatter.points(), for index, (point, counts) in (
histograms_counts): enumerate(zip(self.xy_plot_data.scatter.points(),
histograms_counts))):
point.histogram_index = index
point.histogram_counts = counts point.histogram_counts = counts
self.hist_plot_data = self.hist_plot.plot( self.hist_plot_data = self.hist_plot.plot(
stepMode=True, fillLevel=0, stepMode=True, fillLevel=0,
brush=(0, 0, 255, 150)) 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): def _point_clicked(self, data_item, spot_items):
spot_item = spot_items[0] spot_item = spot_items[0]
position = spot_item.pos() position = spot_item.pos()
@ -61,14 +81,38 @@ class XYHistPlot(pyqtgraph.GraphicsWindow):
self.xy_plot.addItem(self.arrow) self.xy_plot.addItem(self.arrow)
else: else:
self.arrow.setPos(position) self.arrow.setPos(position)
self.selected_index = spot_item.histogram_index
self.hist_plot_data.setData(x=self.histogram_bins, self.hist_plot_data.setData(x=self.histogram_bins,
y=spot_item.histogram_counts) 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): def data_changed(self, data, mods):
xs = data[self.args.xs][1] xs = data[self.args.xs][1]
histogram_bins = data[self.args.histogram_bins][1] histogram_bins = data[self.args.histogram_bins][1]
histograms_counts = data[self.args.histograms_counts][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(): def main():