dylab/HelperClasses/Plotting/WidgetFakeColorPlot.py

139 lines
4.5 KiB
Python
Raw Normal View History

2022-07-30 21:50:53 +02:00
import pyqtgraph as pg
from pyqtgraph import Qt
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
from pyqtgraph.dockarea import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from .DataExtractorLyse import DataExtractorManager
# import DataExtractorLyse
from .WidgetPlot import DataPlot
# import WidgetPlot
from PIL import ImageColor
color_palette_html = ['#1f77b4',
'#ff7f0e',
'#2ca02c',
'#d62728',
'#9467bd',
'#8c564b',
'#e377c2',
'#7f7f7f',
'#bcbd22',
'#17becf']
color_palette = [ImageColor.getcolor(color, "RGB") for color in color_palette_html]
class FakeColorPlot(DataPlot):
def __init__(self, title, data_path=None, **kwargs):
super().__init__(title, **kwargs)
# set data extractor
self.data_extractor_manager = DataExtractorManager(data_path)
self.data_extractor_manager.add_data_extractor('data_img', 'array', data_path)
self.data_extractor_manager.add_data_extractor('x', 'array', (data_path[0], 'x'))
self.data_extractor_manager.add_data_extractor('y', 'array', (data_path[0], 'y'))
self.data_extractor_manager.add_data_extractor('warning', 'single', (data_path[0], 'warning'))
self.setMinimumHeight(550)
self.setMinimumWidth(550)
# Add imaging
self.img = pg.ImageItem()
self.aximg = self.plots.addPlot(title="")
self.aximg.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.plots.nextRow()
self.plots.nextColumn()
self.img.translate(-0.5, -0.5)
self.scalex = 1
self.scaley = 1
self.cx = 0
self.cy = 0
self.data_image = None
def update(self, h5_path):
data = self.data_extractor_manager.get_data(h5_path)
data_img = data['data_img']
x = data['x']
y = data['y']
if x is None:
x = np.linspace(0, data_img.shape[0], data_img.shape[0])
if y is None:
y = np.linspace(0, data_img.shape[1], data_img.shape[1])
warning = data['warning']
# update plots
self.img.setImage(data_img.T)
self.iso.setData(data_img.T)
self.data_img = data_img
# set position and scale of image
newscalex = x[1] - x[0]
newscaley = y[1] - y[0]
transx = (x[0] - (self.cx - 0.5 * self.scalex)) / newscalex - 0.5
transy = (y[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 = x[0]
self.cy = y[0]
# update table and warning
self.update_warning(warning)
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.aximg.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.aximg.setTitle("pos: (%0.1f, %0.1f) value: %g" % (x, y, val))