Source code for scan_framework.applets.plot_xy_ntrace_white

#!/usr/bin/env python3.5
# -*- coding: utf8 -*-
#
#
# Applet for plotting multiple measurements in the NIST scan framework
import numpy as np
import PyQt5  # make sure pyqtgraph imports Qt5
import pyqtgraph
from artiq.applets.simple import SimpleApplet


[docs]class LoadError(Exception): pass
[docs]class XYPlot(pyqtgraph.PlotWidget):
[docs] def __init__(self, args): # colors have to be set before PlotWidget initialised # pyqtgraph.setConfigOption('background', 'w') pyqtgraph.setConfigOption('foreground', 'k') self.args = args self.args_dict = vars(args) pyqtgraph.PlotWidget.__init__(self) self.n_plots = 3
[docs] def load_plot_data(self, data, n): # load y try: key = self.args_dict["y%i" % n] y = data[key][1] except KeyError: raise LoadError # load x x = data.get(self.args_dict["x%i" % n], (False, None))[1] if x is None: x = list(range(len(y))) # load error error = data.get(self.args_dict["error%i"%n], (False, None))[1] if error is not None: if len(np.shape(error)) > 1: error = np.reshape(error[1], np.shape(x)) # load fit fit = data.get(self.args_dict["fit%i"%n], (False, None))[1] if len(np.shape(fit)) > 1: fit = np.reshape(fit[1], np.shape(x)) if len(np.shape(y)) > 1: y = np.reshape(y[1], np.shape(x)) if not len(y) or len(y) != len(x): raise LoadError if error is not None and hasattr(error, "__len__"): if not len(error): error = None elif len(error) != len(y): raise LoadError if fit is not None: if not len(fit): fit = None elif len(fit) != len(y): raise LoadError return x, y, error, fit
[docs] def data_changed(self, data, mods): # load title try: title = self.args.title except KeyError: title = None # load plot data try: plot_data = [[] for _ in range(6)] for i in range(self.n_plots): plot_data[i] = self.load_plot_data(data, i+1) except LoadError: return self.clear() # add plots colors = ['r', 'b', 'g', 'm', 'c','y'] symbols = ['o', 't', 'd', 's', 'd' ] sizes = [10, 12, 15, 10, 10] errcolors = ['k', 'r', 'k', 'r', 'r', 'r', ] for i in range(self.n_plots): (x, y, error, fit) = plot_data[i] c = colors[i % len(colors)] s = symbols[i % len(symbols)] sz = sizes[i % len(sizes)] self.plot(x, y, pen=None, symbol=s, symbolBrush=c, symbolSize=sz) # add errors & fits if error is not None: ec = errcolors[i % len(errcolors)] # See https://github.com/pyqtgraph/pyqtgraph/issues/211 if hasattr(error, "__len__") and not isinstance(error, np.ndarray): error = np.array(error) errbars = pyqtgraph.ErrorBarItem( x=np.array(x), y=np.array(y), height=error, pen=pyqtgraph.mkPen(color=ec, width=1), beam=np.array((max(x) - min(x)) / len(x) / 10)) self.addItem(errbars) if fit is not None: xi = np.argsort(x) self.plot(x[xi], fit[xi], pen=pyqtgraph.mkPen(color='r', width=2), shadowPen=pyqtgraph.mkPen(color='w', width=3)) # axes & title x_axis = self.getAxis('bottom') y_axis = self.getAxis('left') axis_font = PyQt5.QtGui.QFont() axis_font.setPixelSize(20) x_axis.tickFont = axis_font # somehow tickTextOffset necessary to change tick font x_axis.setStyle(tickTextOffset=30) y_axis.tickFont = axis_font y_axis.setStyle(tickTextOffset=30) x_axis.enableAutoSIPrefix(False) label_style = {'font-size': '20pt', "font-bold": "False"} self.setLabel('bottom', self.args.x_label, units=self.args.x_units, **label_style) self.setLabel('left', self.args.y_label, units=self.args.y_units, **label_style) self.setTitle(title, size='20px')
[docs]def main(): applet = SimpleApplet(XYPlot) n_plots = 3 for i in range(1, n_plots+1): applet.add_dataset("y%i" % i, "y%i values" % i) applet.add_dataset("x%i" % i, "x%i values" % i, required=False) applet.add_dataset("error%i" % i, "Error bars for each Y%i value" % i, required=False) applet.add_dataset("fit%i" % i, "Fit values for each Y%i value" % i, required=False) applet.add_dataset("x_label", 'x-axis label', required=False) applet.add_dataset("x_units", 'x-axis units', required=False) applet.add_dataset("y_label", 'y-axis label', required=False) applet.add_dataset("y_units", 'y-axis label', required=False) applet.add_dataset("title", "plot title", required=False) applet.run()
if __name__ == "__main__": main()