gui: support X axis, fit, error bars in XY plot

This commit is contained in:
Sebastien Bourdeauducq 2015-08-06 18:02:30 +08:00
parent 7180552d24
commit 263ff86e66
1 changed files with 59 additions and 39 deletions

View File

@ -1,4 +1,5 @@
from collections import OrderedDict from collections import OrderedDict
import numpy as np
from quamash import QtGui from quamash import QtGui
import pyqtgraph as pg import pyqtgraph as pg
@ -47,24 +48,30 @@ class _SimpleSettings(_BaseSettings):
_BaseSettings.__init__(self, parent, self._window_title, _BaseSettings.__init__(self, parent, self._window_title,
prev_name, create_cb) prev_name, create_cb)
self.grid.addWidget(QtGui.QLabel("Result:")) self.result_widgets = dict()
self.result = QtGui.QComboBox() for row, (has_none, key) in enumerate(self._result_keys):
self.grid.addWidget(self.result, 1, 1) self.grid.addWidget(QtGui.QLabel(key.capitalize() + ":"))
self.result.addItems(result_list) w = QtGui.QComboBox()
self.result.setEditable(True) self.grid.addWidget(w, row + 1, 1)
if "result" in prev_settings: if has_none:
self.result.setEditText(prev_settings["result"]) w.addItem("<None>")
w.addItems(result_list)
w.setEditable(True)
if key in prev_settings:
w.setEditText(prev_settings[key])
self.result_widgets[key] = w
self.add_buttons() self.add_buttons()
def validate_input(self): def validate_input(self):
return bool(self.result.currentText()) return all(w.currentText() for w in self.result_widgets.values())
def get_input(self): def get_input(self):
return {"result": self.result.currentText()} return {k: v.currentText() for k, v in self.result_widgets.items()}
class NumberDisplaySettings(_SimpleSettings): class NumberDisplaySettings(_SimpleSettings):
_window_title = "Number display" _window_title = "Number display"
_result_keys = [(False, "result")]
class NumberDisplay(dockarea.Dock): class NumberDisplay(dockarea.Dock):
@ -90,6 +97,7 @@ class NumberDisplay(dockarea.Dock):
class XYDisplaySettings(_SimpleSettings): class XYDisplaySettings(_SimpleSettings):
_window_title = "XY plot" _window_title = "XY plot"
_result_keys = [(False, "y"), (True, "x"), (True, "error"), (True, "fit")]
class XYDisplay(dockarea.Dock): class XYDisplay(dockarea.Dock):
@ -101,44 +109,56 @@ class XYDisplay(dockarea.Dock):
self.addWidget(self.plot) self.addWidget(self.plot)
def data_sources(self): def data_sources(self):
return {self.settings["result"]} s = {self.settings["y"]}
for k in "x", "error", "fit":
if self.settings[k] != "<None>":
s.add(self.settings[k])
return s
def update_data(self, data): def update_data(self, data):
result = self.settings["result"] result_y = self.settings["y"]
result_x = self.settings["x"]
result_error = self.settings["error"]
result_fit = self.settings["fit"]
try: try:
y = data[result] y = data[result_y]
except KeyError: except KeyError:
return return
self.plot.clear() x = data.get(result_x, None)
if not y: if x is None:
x = list(range(len(y)))
error = data.get(result_error, None)
fit = data.get(result_fit, None)
if not y or len(y) != len(x):
return return
self.plot.plot(y) if error is not None and hasattr(error, "__len__"):
if not len(error):
error = None
elif len(error) != len(y):
return
if fit is not None:
if not len(fit):
fit = None
elif len(fit) != len(y):
return
self.plot.clear()
self.plot.plot(x, y, pen=None, symbol="x")
if error is not None:
# See https://github.com/pyqtgraph/pyqtgraph/issues/211
if hasattr(error, "__len__") and not isinstance(error, np.ndarray):
error = np.array(error)
errbars = pg.ErrorBarItem(x=np.array(x), y=np.array(y), height=error)
self.plot.addItem(errbars)
if fit is not None:
self.plot.plot(x, fit)
class HistogramDisplaySettings(_BaseSettings): class HistogramDisplaySettings(_SimpleSettings):
def __init__(self, parent, prev_name, prev_settings, _window_title = "Histogram"
result_list, create_cb): _result_keys = [(False, "y"), (True, "x")]
_BaseSettings.__init__(self, parent, "Histogram",
prev_name, create_cb)
for row, axis in enumerate("yx"):
self.grid.addWidget(QtGui.QLabel(axis.upper() + ":"))
w = QtGui.QComboBox()
self.grid.addWidget(w, row + 1, 1)
if axis == "x":
w.addItem("<None>")
w.addItems(result_list)
w.setEditable(True)
if axis in prev_settings:
w.setEditText(prev_settings["y"])
setattr(self, axis, w)
self.add_buttons()
def validate_input(self):
return bool(self.y.currentText()) and bool(self.x.currentText())
def get_input(self):
return {"y": self.y.currentText(), "x": self.x.currentText()}
class HistogramDisplay(dockarea.Dock): class HistogramDisplay(dockarea.Dock):