dylab/HelperClasses/Plotting/WidgetQuick2DPlot.py

166 lines
5.6 KiB
Python
Raw Normal View History

2022-07-30 21:50:53 +02:00
class Quick2DPlot(QuickDataPlot):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.img = pg.ImageItem()
self.plot.addItem(self.img)
# Isocurve draplotsg
self.iso = pg.IsocurveItem(level=1000, pen=color_palette[2])
self.iso.setParentItem(self.img)
self.iso.setZValue(5)
# Contrast/color control
self.hist = pg.HistogramLUTItem()
self.hist.setImageItem(self.img)
self.plots.addItem(self.hist)
# Draggable line for setting isocurve level
self.isoLine = pg.InfiniteLine(angle=0, movable=True, pen=color_palette[2])
self.hist.vb.addItem(self.isoLine)
self.hist.vb.setMouseEnabled(y=False) # makes user interaction a little easier
self.isoLine.setValue(1000)
self.isoLine.setZValue(1000) # bring iso line above contrast controls
self.isoLine.sigDragged.connect(self.updateIsocurve)
# Monkey-patch the image to use our custom hover function.
# This is generally discouraged (you should subclass ImageItem instead),
# but it works for a very simple use like this.
self.img.hoverEvent = self.imageHoverEvent
self.img.translate(-0.5, -0.5)
self.scalex = 1
self.scaley = 1
self.cx = 0
self.cy = 0
self.nplots = 0
self.table.setColumnCount(3)
self.table.setRowCount(2)
self.table.setColumnWidth(0, 200)
self.table.setColumnWidth(1, 150)
self.table.setColumnWidth(2, 150)
self.table.setHorizontalHeaderLabels(['xvalue', 'yarray', 'zarray'])
self.combox = NumericDataCombo(self.ap.df)
self.comboy = NumericDataCombo(self.ap.df)
self.comboz = NumericDataCombo(self.ap.df)
self.table.setCellWidget(0, 0, self.combox)
self.table.setCellWidget(0, 1, self.comboy)
self.table.setCellWidget(0, 2, self.comboz)
self.mk_buttons()
def mk_buttons(self):
self.bt_update = QPushButton('Update', self)
self.bt_update.clicked.connect(self.update_from_h5)
self.table.setCellWidget(1, 1, self.bt_update)
def update_data_extractor(self):
idxx = self.combox.get_idx()
idxy = self.comboy.get_idx()
idxz = self.comboz.get_idx()
if idxx not in self.data_extractor.data_extractors:
if idxx[0] == 'shot number':
self.data_extractor[idxx] = EmptyDataExtractor()
else:
self.data_extractor[idxx] = SingleDataExtractor(idxx)
if idxy not in self.data_extractor.data_extractors:
if idxy[0] == 'shot number':
self.data_extractor[idxy] = EmptyDataExtractor()
else:
self.data_extractor[idxy] = SingleDataExtractor(idxy)
if idxz not in self.data_extractor.data_extractors:
if idxz[0] == 'shot number':
self.data_extractor[idxz] = EmptyDataExtractor()
else:
self.data_extractor[idxz] = SingleDataExtractor(idxz)
self.data_extractor.clean_children([idxx, idxy, idxz])
self.data_extractor.clean_memory(self.ap.h5_paths)
def update(self, murks=None):
xs = np.array([])
ys = np.array([])
zs = np.array([])
idxx = self.combox.get_idx()
idxy = self.comboy.get_idx()
idxz = self.comboz.get_idx()
for i, h5_path in enumerate(self.ap.h5_paths_selected):
data = self.data_extractor.get_data(h5_path)[0]
if idxx[0] == 'shot number':
xs = np.append(xs, self.ap.shotselector.get_selected_indices()[0][i])
else:
xs = np.append(xs, data[idxx])
if idxy[0] == 'shot number':
ys = np.append(ys, self.ap.shotselector.get_selected_indices()[0][i])
else:
ys = np.append(ys, data[idxy])
if idxz[0] == 'shot number':
zs = np.append(zs, self.ap.shotselector.get_selected_indices()[0][i])
else:
zs = np.append(zs, data[idxz])
# here we don't want to assume that the data is on a grid
# this can happen if the parameters where changed between two sweeps
xi = np.linspace(xs.min(), xs.max(), 200)
yi = np.linspace(ys.min(), ys.max(), 200)
Xi, Yi = np.meshgrid(xi, yi)
Zi = griddata((xs, ys), zs, (Xi, Yi), 'nearest')
self.img.setImage(Zi.T)
self.iso.setData(Zi.T)
self.data_img = Zi
# set position and scale of image
newscalex = xi[1] - xi[0]
newscaley = yi[1] - yi[0]
transx = (xi[0] - (self.cx - 0.5 * self.scalex)) / newscalex - 0.5
transy = (yi[0] - (self.cy - 0.5 * self.scaley)) / newscaley - 0.5
self.img.scale(newscalex / self.scalex, newscaley / self.scaley)
self.img.translate(transx, transy)
self.scalex = newscalex
self.scaley = newscaley
self.cx = xi[0]
self.cy = yi[0]
def updateIsocurve(self):
self.iso.setLevel(self.isoLine.value())
def imageHoverEvent(self, event):
"""Show the position, pixel, and value under the mouse cursor.
"""
if event.isExit():
self.plot.setTitle("")
return
pos = event.pos()
i, j = pos.y(), pos.x()
i = int(np.clip(i, 0, self.data_img.shape[0] - 1))
j = int(np.clip(j, 0, self.data_img.shape[1] - 1))
val = self.data_img[i, j]
ppos = self.img.mapToParent(pos)
x, y = ppos.x(), ppos.y()
self.plot.setTitle("pos: (%0.1f, %0.1f) value: %g" % (x, y, val))