0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-14 03:31:50 +02:00

feat(figure): changes to support direct plot functionality

This commit is contained in:
2024-05-24 10:03:40 +02:00
parent a47a8ec413
commit fc4d0f3bb2
9 changed files with 72 additions and 37 deletions

View File

@ -554,17 +554,17 @@ class BECFigure(RPCBase):
@rpc_call @rpc_call
def plot( def plot(
self, self,
x_name: "str" = None, x: "list | np.ndarray | None" = None,
y_name: "str" = None, y: "list | np.ndarray | None" = None,
z_name: "str" = None, x_name: "str | None" = None,
x_entry: "str" = None, y_name: "str | None" = None,
y_entry: "str" = None, z_name: "str | None" = None,
z_entry: "str" = None, x_entry: "str | None" = None,
x: "list | np.ndarray" = None, y_entry: "str | None" = None,
y: "list | np.ndarray" = None, z_entry: "str | None" = None,
color: "Optional[str]" = None, color: "str | None" = None,
color_map_z: "Optional[str]" = "plasma", color_map_z: "str | None" = "plasma",
label: "Optional[str]" = None, label: "str | None" = None,
validate: "bool" = True, validate: "bool" = True,
**axis_kwargs, **axis_kwargs,
) -> "BECWaveform": ) -> "BECWaveform":
@ -572,14 +572,14 @@ class BECFigure(RPCBase):
Add a 1D waveform plot to the figure. Always access the first waveform widget in the figure. Add a 1D waveform plot to the figure. Always access the first waveform widget in the figure.
Args: Args:
x(list | np.ndarray): Custom x data to plot.
y(list | np.ndarray): Custom y data to plot.
x_name(str): The name of the device for the x-axis. x_name(str): The name of the device for the x-axis.
y_name(str): The name of the device for the y-axis. y_name(str): The name of the device for the y-axis.
z_name(str): The name of the device for the z-axis. z_name(str): The name of the device for the z-axis.
x_entry(str): The name of the entry for the x-axis. x_entry(str): The name of the entry for the x-axis.
y_entry(str): The name of the entry for the y-axis. y_entry(str): The name of the entry for the y-axis.
z_entry(str): The name of the entry for the z-axis. z_entry(str): The name of the entry for the z-axis.
x(list | np.ndarray): Custom x data to plot.
y(list | np.ndarray): Custom y data to plot.
color(str): The color of the curve. color(str): The color of the curve.
color_map_z(str): The color map to use for the z-axis. color_map_z(str): The color map to use for the z-axis.
label(str): The label of the curve. label(str): The label of the curve.

View File

@ -93,7 +93,7 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
self.console.set_default_style("linux") self.console.set_default_style("linux")
def _init_figure(self): def _init_figure(self):
self.figure.plot("samx", "bpm4d") self.figure.plot(x_name="samx", y_name="bpm4d")
self.figure.motor_map("samx", "samy") self.figure.motor_map("samx", "samy")
self.figure.image("eiger", color_map="viridis", vrange=(0, 100)) self.figure.image("eiger", color_map="viridis", vrange=(0, 100))
@ -124,7 +124,7 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
self.d2 = self.dock.add_dock(widget=self.label_1, position="right") self.d2 = self.dock.add_dock(widget=self.label_1, position="right")
self.d3 = self.dock.add_dock(name="figure") self.d3 = self.dock.add_dock(name="figure")
self.fig_dock3 = BECFigure() self.fig_dock3 = BECFigure()
self.fig_dock3.plot("samx", "bpm4d") self.fig_dock3.plot(x_name="samx", y_name="bpm4d")
self.d3.add_widget(self.label_3) self.d3.add_widget(self.label_3)
self.d3.add_widget(self.button_3) self.d3.add_widget(self.button_3)
self.d3.add_widget(self.fig_dock3) self.d3.add_widget(self.fig_dock3)

View File

@ -11,6 +11,7 @@ import qdarktheme
from pydantic import Field from pydantic import Field
from qtpy.QtCore import Signal as pyqtSignal from qtpy.QtCore import Signal as pyqtSignal
from qtpy.QtWidgets import QWidget from qtpy.QtWidgets import QWidget
from typeguard import typechecked
from bec_widgets.utils import BECConnector, ConnectionConfig, WidgetContainerUtils from bec_widgets.utils import BECConnector, ConnectionConfig, WidgetContainerUtils
from bec_widgets.widgets.figure.plots.image.image import BECImageShow, ImageConfig from bec_widgets.widgets.figure.plots.image.image import BECImageShow, ImageConfig
@ -261,19 +262,20 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
return waveform return waveform
@typechecked
def plot( def plot(
self, self,
x_name: str = None, x: list | np.ndarray | None = None,
y_name: str = None, y: list | np.ndarray | None = None,
z_name: str = None, x_name: str | None = None,
x_entry: str = None, y_name: str | None = None,
y_entry: str = None, z_name: str | None = None,
z_entry: str = None, x_entry: str | None = None,
x: list | np.ndarray = None, y_entry: str | None = None,
y: list | np.ndarray = None, z_entry: str | None = None,
color: Optional[str] = None, color: str | None = None,
color_map_z: Optional[str] = "plasma", color_map_z: str | None = "plasma",
label: Optional[str] = None, label: str | None = None,
validate: bool = True, validate: bool = True,
**axis_kwargs, **axis_kwargs,
) -> BECWaveform: ) -> BECWaveform:
@ -281,14 +283,14 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
Add a 1D waveform plot to the figure. Always access the first waveform widget in the figure. Add a 1D waveform plot to the figure. Always access the first waveform widget in the figure.
Args: Args:
x(list | np.ndarray): Custom x data to plot.
y(list | np.ndarray): Custom y data to plot.
x_name(str): The name of the device for the x-axis. x_name(str): The name of the device for the x-axis.
y_name(str): The name of the device for the y-axis. y_name(str): The name of the device for the y-axis.
z_name(str): The name of the device for the z-axis. z_name(str): The name of the device for the z-axis.
x_entry(str): The name of the entry for the x-axis. x_entry(str): The name of the entry for the x-axis.
y_entry(str): The name of the entry for the y-axis. y_entry(str): The name of the entry for the y-axis.
z_entry(str): The name of the entry for the z-axis. z_entry(str): The name of the entry for the z-axis.
x(list | np.ndarray): Custom x data to plot.
y(list | np.ndarray): Custom y data to plot.
color(str): The color of the curve. color(str): The color of the curve.
color_map_z(str): The color map to use for the z-axis. color_map_z(str): The color map to use for the z-axis.
label(str): The label of the curve. label(str): The label of the curve.
@ -307,6 +309,27 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
else: else:
waveform = self.add_plot(**axis_kwargs) waveform = self.add_plot(**axis_kwargs)
if x is not None and y is None:
if isinstance(x, np.ndarray):
if x.ndim == 1:
y = np.arange(x.size)
waveform.add_curve_custom(x=np.arange(x.size), y=x, color=color, label=label)
return waveform
if x.ndim == 2:
waveform.add_curve_custom(x=x[:, 0], y=x[:, 1], color=color, label=label)
return waveform
elif isinstance(x, list):
y = np.arange(len(x))
waveform.add_curve_custom(x=np.arange(len(x)), y=x, color=color, label=label)
return waveform
else:
raise ValueError(
"Invalid input. Provide either device names (x_name, y_name) or custom data."
)
if x is not None and y is not None:
waveform.add_curve_custom(x=x, y=y, color=color, label=label)
return waveform
# User wants to add scan curve -> 1D Waveform # User wants to add scan curve -> 1D Waveform
if x_name is not None and y_name is not None and z_name is None and x is None and y is None: if x_name is not None and y_name is not None and z_name is None and x is None and y is None:
waveform.add_curve_scan( waveform.add_curve_scan(

View File

@ -38,7 +38,7 @@ def test_rpc_add_dock_with_figure_e2e(rpc_server_dock, qtbot):
assert fig2.__class__ == BECFigure assert fig2.__class__ == BECFigure
mm = fig0.motor_map("samx", "samy") mm = fig0.motor_map("samx", "samy")
plt = fig1.plot("samx", "bpm4i") plt = fig1.plot(x_name="samx", y_name="bpm4i")
im = fig2.image("eiger") im = fig2.image("eiger")
assert mm.__class__.__name__ == "BECMotorMap" assert mm.__class__.__name__ == "BECMotorMap"

View File

@ -23,7 +23,7 @@ def test_rpc_plotting_shortcuts_init_configs(rpc_server_figure, qtbot):
fig = BECFigure(rpc_server_figure.gui_id) fig = BECFigure(rpc_server_figure.gui_id)
fig_server = rpc_server_figure.gui fig_server = rpc_server_figure.gui
plt = fig.plot("samx", "bpm4i") plt = fig.plot(x_name="samx", y_name="bpm4i")
im = fig.image("eiger") im = fig.image("eiger")
motor_map = fig.motor_map("samx", "samy") motor_map = fig.motor_map("samx", "samy")
plt_z = fig.add_plot("samx", "samy", "bpm4i") plt_z = fig.add_plot("samx", "samy", "bpm4i")
@ -79,9 +79,9 @@ def test_rpc_waveform_scan(rpc_server_figure, qtbot):
fig = BECFigure(rpc_server_figure.gui_id) fig = BECFigure(rpc_server_figure.gui_id)
# add 3 different curves to track # add 3 different curves to track
plt = fig.plot("samx", "bpm4i") plt = fig.plot(x_name="samx", y_name="bpm4i")
fig.plot("samx", "bpm3a") fig.plot(x_name="samx", y_name="bpm3a")
fig.plot("samx", "bpm4d") fig.plot(x_name="samx", y_name="bpm4d")
client = rpc_server_figure.client client = rpc_server_figure.client
dev = client.device_manager.devices dev = client.device_manager.devices

View File

@ -22,7 +22,7 @@ def test_rpc_register_list_connections(rpc_server_figure, rpc_register, qtbot):
fig = BECFigure(rpc_server_figure.gui_id) fig = BECFigure(rpc_server_figure.gui_id)
fig_server = rpc_server_figure.gui fig_server = rpc_server_figure.gui
plt = fig.plot("samx", "bpm4i") plt = fig.plot(x_name="samx", y_name="bpm4i")
im = fig.image("eiger") im = fig.image("eiger")
motor_map = fig.motor_map("samx", "samy") motor_map = fig.motor_map("samx", "samy")
plt_z = fig.add_plot("samx", "samy", "bpm4i") plt_z = fig.add_plot("samx", "samy", "bpm4i")

View File

@ -59,7 +59,7 @@ def test_bec_dock_area_add_remove_dock(bec_dock_area, qtbot):
def test_add_remove_bec_figure_to_dock(bec_dock_area): def test_add_remove_bec_figure_to_dock(bec_dock_area):
d0 = bec_dock_area.add_dock() d0 = bec_dock_area.add_dock()
fig = d0.add_widget_bec("BECFigure") fig = d0.add_widget_bec("BECFigure")
plt = fig.plot("samx", "bpm4i") plt = fig.plot(x_name="samx", y_name="bpm4i")
im = fig.image("eiger") im = fig.image("eiger")
mm = fig.motor_map("samx", "samy") mm = fig.motor_map("samx", "samy")

View File

@ -65,7 +65,7 @@ def test_bec_figure_add_remove_plot(bec_figure):
def test_add_different_types_of_widgets(bec_figure): def test_add_different_types_of_widgets(bec_figure):
plt = bec_figure.plot("samx", "bpm4i") plt = bec_figure.plot(x_name="samx", y_name="bpm4i")
im = bec_figure.image("eiger") im = bec_figure.image("eiger")
motor_map = bec_figure.motor_map("samx", "samy") motor_map = bec_figure.motor_map("samx", "samy")
@ -228,7 +228,7 @@ def test_clear_all(bec_figure):
def test_shortcuts(bec_figure): def test_shortcuts(bec_figure):
plt = bec_figure.plot("samx", "bpm4i") plt = bec_figure.plot(x_name="samx", y_name="bpm4i")
im = bec_figure.image("eiger") im = bec_figure.image("eiger")
motor_map = bec_figure.motor_map("samx", "samy") motor_map = bec_figure.motor_map("samx", "samy")

View File

@ -304,6 +304,18 @@ def test_set_custom_curve_data(bec_figure, qtbot):
assert np.array_equal(y_new, [7, 8, 9]) assert np.array_equal(y_new, [7, 8, 9])
def test_custom_data_2D_array(bec_figure, qtbot):
data = np.random.rand(10, 2)
plt = bec_figure.plot(data)
x, y = plt.curves[0].get_data()
assert np.array_equal(x, data[:, 0])
assert np.array_equal(y, data[:, 1])
def test_get_all_data(bec_figure): def test_get_all_data(bec_figure):
w1 = bec_figure.add_plot() w1 = bec_figure.add_plot()