0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-13 11:11:49 +02:00

feat: add auto-computed color_list from colormaps

This commit is contained in:
2023-07-18 14:16:25 +02:00
parent 10e2906445
commit 3e1708bf48

View File

@ -2,7 +2,7 @@ from typing import Any
import numpy as np
import pyqtgraph as pg
from pyqtgraph import mkPen, mkBrush
from pyqtgraph import mkPen, mkBrush, mkColor
from pyqtgraph.Qt import QtCore, QtWidgets, uic
from pyqtgraph.Qt.QtCore import pyqtSignal
@ -31,31 +31,37 @@ class BasicPlot(QtWidgets.QWidget):
self.plotter_data_y = []
self.curves = []
self.pens = []
self.brushs = []
self.plotter_scan_id = None
# TODO to be moved to utils function
plotstyles = {
"symbol": "o",
"symbolSize": 12,
"symbolSize": 10,
}
color_list = ["#384c6b", "#e28a2b", "#5E3023", "#e41a1c", "#984e83", "#4daf4a"]
color_list = BasicPlot.golden_angle_color(colormap="viridis", num=len(self.y_value_list))
# setup plots
self.plot = self.plot_window.getPlotItem()
for ii in range(len(self.y_value_list)):
if ii < len(color_list):
pen = mkPen(color=color_list[ii], width=2, style=QtCore.Qt.DashLine)
brush = mkBrush(color=color_list[ii])
else:
color = list(np.random.choice(range(255), size=3))
pen = mkPen(
color=list(np.random.choice(range(255), size=3)),
color=color,
width=2,
style=QtCore.Qt.DashLine,
)
curve = pg.ScatterPlotItem(**plotstyles, pen=pen, skipFiniteCheck=True)
brush = mkBrush(color=color)
curve = pg.PlotDataItem(**plotstyles, symbolBrush=brush, pen=pen, skipFiniteCheck=True)
self.plot.addItem(curve)
self.curves.append(curve)
self.pens.append(pen)
self.brushs.append(brush)
# self.plot.plot(**plotstyles)
# self.plot_data = self.plot.plot([], [], **plotstyles, pen=self.pen, title=name)
@ -86,17 +92,22 @@ class BasicPlot(QtWidgets.QWidget):
closest_point = self.closest_x_y_value(
mousePoint.x(), self.plotter_data_x, self.plotter_data_y[ii]
)
# TODO fix text wobble in plot, see plot when it crosses 0
x_data = f"{closest_point[0]:.{self.precision}f}"
y_data = f"{closest_point[1]:.{self.precision}f}"
string_cap = 10
self.mouse_box_data.setText(
"".join(
[
self.mouse_box_data.text(),
"\n",
f"<p'FONT COLOR=red';>", # rgba{self.pens[ii].color().getRgb()
# TODO fix different fonts for mouse cursor!
# f"<p'FONT COLOR=red';>", # rgba{self.pens[ii].color().getRgb()
f"{y_value}",
"\n",
f"X_data: {closest_point[0]:.{self.precision}f}",
f"X_data: {x_data:>string_cap}",
"\n",
f"Y_data: {closest_point[1]:.{self.precision}f}</p>",
f"Y_data: {y_data:>string_cap}",
]
)
# f"Mouse cursor\n"
@ -137,7 +148,7 @@ class BasicPlot(QtWidgets.QWidget):
self.precision = client.device_manager.devices[scan_motors[0]]._info["describe"][
scan_motors[0]
]["precision"]
# TODO
# TODO after update of bec_lib, this will be new way to access data
# self.precision = client.device_manager.devices[scan_motors[0]].precision
x = data["data"][scan_motors[0]][scan_motors[0]]["value"]
self.plotter_data_x.append(x)
@ -159,6 +170,38 @@ class BasicPlot(QtWidgets.QWidget):
self.plotter_data_y.append([])
self.mouse_box_data.setText("Mouse cursor") # Crashes the Thread
@staticmethod
def golden_ratio(num: int):
# get the first num golden angles
phi = 2 * np.pi * ((1 + np.sqrt(5)) / 2)
angles = []
for ii in range(num):
x = np.cos(ii * phi)
y = np.sin(ii * phi)
angle = np.arctan2(y, x)
angles.append(angle)
return angles
@staticmethod
def golden_angle_color(colormap: str, num: int):
cmap = pg.colormap.get(colormap)
cmap_colors = cmap.color
if num > len(cmap_colors):
raise ValueError(
f"Number of colors requested ({num}) is greater than the number of colors in the colormap ({len(cmap_colors)})"
)
angles = BasicPlot.golden_ratio(len(cmap_colors))
color_selection = np.round(np.interp(angles, (-np.pi, np.pi), (0, len(cmap_colors))))
colors = [
mkColor(tuple((cmap_colors[int(ii)] * 255).astype(int))) for ii in color_selection[:num]
]
return colors
@staticmethod
def rgb_to_hex(rgb: np.ndarray) -> str:
rgb = rgb.reshape(3)
return "#{:02X}{:02X}{:02X}".format(*rgb)
if __name__ == "__main__":
import argparse
@ -167,7 +210,10 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"--signals", help="specify recorded signals", nargs="+", default=["gauss_bpm"]
"--signals",
help="specify recorded signals",
nargs="+",
default=["gauss_bpm", "bpm4i", "bpm5i", "bpm6i"],
)
value = parser.parse_args()
print(f"Plotting signals for: {', '.join(value.signals)}")