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

fix(image): image can be fully reconstructed from config

This commit is contained in:
2024-06-27 16:23:05 +02:00
parent b8f796fd3f
commit 797f73c39a
6 changed files with 198 additions and 253 deletions

View File

@ -40,6 +40,10 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
"w1": self.w1,
"w2": self.w2,
"w3": self.w3,
"w1_c": self.w1_c,
"w2_c": self.w2_c,
"w3_c": self.w3_c,
"w4": self.w4,
"d0": self.d0,
"d1": self.d1,
"d2": self.d2,
@ -75,13 +79,31 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
self.figure.plot(x_name="samx", y_name="samy", z_name="bpm4i", color_map_z="cividis")
self.figure.motor_map("samx", "samy")
self.figure.image("eiger", color_map="viridis", vrange=(0, 100))
self.figure.add_plot(x_name="samx", y_name="samy", z_name="bpm4i", color_map_z="magma")
self.figure.plot(
x_name="samx", y_name="samy", z_name="bpm4i", color_map_z="magma", new=True
)
self.figure.change_layout(2, 2)
self.w1 = self.figure[0, 0]
self.w2 = self.figure[0, 1]
self.w3 = self.figure[1, 0]
self.w4 = self.figure[1, 1]
# Plot Customisation
self.w1.set_title("Waveform 1")
self.w1.set_x_label("Motor Position (samx)")
self.w1.set_y_label("Intensity A.U.")
# Image Customisation
self.w3.set_title("Eiger Image")
self.w3.set_x_label("X")
self.w3.set_y_label("Y")
# Configs to try to pass
self.w1_c = self.w1.config_dict
self.w2_c = self.w2.config_dict
self.w3_c = self.w3.config_dict
# curves for w1
self.c1 = self.w1.get_config()

View File

@ -36,10 +36,10 @@ class WidgetHandler:
def __init__(self):
self.widget_factory = {
"PlotBase": (BECPlotBase, SubplotConfig),
"Waveform1D": (BECWaveform, Waveform1DConfig),
"ImShow": (BECImageShow, ImageConfig),
"MotorMap": (BECMotorMap, MotorMapConfig),
"BECPlotBase": (BECPlotBase, SubplotConfig),
"BECWaveform": (BECWaveform, Waveform1DConfig),
"BECImageShow": (BECImageShow, ImageConfig),
"BECMotorMap": (BECMotorMap, MotorMapConfig),
}
def create_widget(
@ -94,9 +94,6 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
"config_dict",
"axes",
"widgets",
"add_plot",
"add_image",
"add_motor_map",
"plot",
"image",
"motor_map",
@ -107,6 +104,12 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
"get_all_rpc",
"widget_list",
]
subplot_map = {
"PlotBase": BECPlotBase,
"BECWaveform": BECWaveform,
"BECImageShow": BECImageShow,
"BECMotorMap": BECMotorMap,
}
clean_signal = pyqtSignal()
@ -200,7 +203,7 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
label: str | None = None,
validate: bool = True,
dap: str | None = None,
):
) -> BECWaveform:
"""
Configure the waveform based on the provided parameters.
@ -279,75 +282,6 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
return waveform
def add_plot(
self,
x: list | np.ndarray = None,
y: list | np.ndarray = None,
x_name: str = None,
y_name: str = None,
z_name: str = None,
x_entry: str = None,
y_entry: str = None,
z_entry: str = None,
color: Optional[str] = None,
color_map_z: Optional[str] = "plasma",
label: Optional[str] = None,
validate: bool = True,
row: int = None,
col: int = None,
config=None,
dap: str | None = None,
**axis_kwargs,
) -> BECWaveform:
"""
Add a Waveform1D plot to the figure at the specified position.
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.
y_name(str): The name of the device for the y-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.
y_entry(str): The name of the entry for the y-axis.
z_entry(str): The name of the entry for the z-axis.
color(str): The color of the curve.
color_map_z(str): The color map to use for the z-axis.
label(str): The label of the curve.
validate(bool): If True, validate the device names and entries.
row(int): The row coordinate of the widget in the figure. If not provided, the next empty row will be used.
col(int): The column coordinate of the widget in the figure. If not provided, the next empty column will be used.
config(dict): Additional configuration for the widget.
**axis_kwargs(dict): Additional axis properties to set on the widget after creation.
"""
widget_id = str(uuid.uuid4())
waveform = self.add_widget(
widget_type="Waveform1D",
widget_id=widget_id,
row=row,
col=col,
config=config,
**axis_kwargs,
)
waveform = self._init_waveform(
waveform=waveform,
x=x,
y=y,
x_name=x_name,
y_name=y_name,
z_name=z_name,
x_entry=x_entry,
y_entry=y_entry,
z_entry=z_entry,
color=color,
color_map_z=color_map_z,
label=label,
validate=validate,
dap=dap,
)
return waveform
@typechecked
def plot(
self,
@ -363,6 +297,9 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
color_map_z: str | None = "plasma",
label: str | None = None,
validate: bool = True,
new: bool = False,
row: int | None = None,
col: int | None = None,
dap: str | None = None,
config: dict | None = None, # TODO make logic more transparent
**axis_kwargs,
@ -383,6 +320,9 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
color_map_z(str): The color map to use for the z-axis.
label(str): The label of the curve.
validate(bool): If True, validate the device names and entries.
new(bool): If True, create a new plot instead of using the first plot.
row(int): The row coordinate of the widget in the figure. If not provided, the next empty row will be used.
col(int): The column coordinate of the widget in the figure. If not provided, the next empty column will be used.
dap(str): The DAP model to use for the curve.
config(dict): Recreates the whole BECWaveform widget from provided configuration.
**axis_kwargs: Additional axis properties to set on the widget after creation.
@ -390,19 +330,13 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
Returns:
BECWaveform: The waveform plot widget.
"""
waveform = self.subplot_factory(
widget_type="BECWaveform", config=config, row=row, col=col, new=new, **axis_kwargs
)
if config is not None:
waveform = self.add_plot(config=config, **axis_kwargs)
return waveform
waveform = WidgetContainerUtils.find_first_widget_by_class(
self._widgets, BECWaveform, can_fail=True
)
if waveform is not None:
if axis_kwargs:
waveform.set(**axis_kwargs)
else:
waveform = self.add_plot(**axis_kwargs)
# Passing args to init_waveform
waveform = self._init_waveform(
waveform=waveform,
x=x,
@ -419,7 +353,6 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
validate=validate,
dap=dap,
)
# TODO remove repetition from .plot method
return waveform
def _init_image(
@ -466,6 +399,10 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
color_map: str = "magma",
data: np.ndarray = None,
vrange: tuple[float, float] = None,
new: bool = False,
row: int | None = None,
col: int | None = None,
config: dict | None = None,
**axis_kwargs,
) -> BECImageShow:
"""
@ -477,78 +414,22 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
color_map(str): The color map to use for the image.
data(np.ndarray): Custom data to display.
vrange(tuple[float, float]): The range of values to display.
**axis_kwargs: Additional axis properties to set on the widget after creation.
Returns:
BECImageShow: The image widget.
"""
image = WidgetContainerUtils.find_first_widget_by_class(
self._widgets, BECImageShow, can_fail=True
)
if image is not None:
if axis_kwargs:
image.set(**axis_kwargs)
else:
image = self.add_image(color_bar=color_bar, **axis_kwargs)
image = self._init_image(
image=image,
monitor=monitor,
color_bar=color_bar,
color_map=color_map,
data=data,
vrange=vrange,
)
return image
def add_image(
self,
monitor: str = None,
color_bar: Literal["simple", "full"] = "full",
color_map: str = "magma",
data: np.ndarray = None,
vrange: tuple[float, float] = None,
row: int = None,
col: int = None,
config=None,
**axis_kwargs,
) -> BECImageShow:
"""
Add an image to the figure at the specified position.
Args:
monitor(str): The name of the monitor to display.
color_bar(Literal["simple","full"]): The type of color bar to display.
color_map(str): The color map to use for the image.
data(np.ndarray): Custom data to display.
vrange(tuple[float, float]): The range of values to display.
new(bool): If True, create a new plot instead of using the first plot.
row(int): The row coordinate of the widget in the figure. If not provided, the next empty row will be used.
col(int): The column coordinate of the widget in the figure. If not provided, the next empty column will be used.
config(dict): Additional configuration for the widget.
config(dict): Recreates the whole BECImageShow widget from provided configuration.
**axis_kwargs: Additional axis properties to set on the widget after creation.
Returns:
BECImageShow: The image widget.
"""
widget_id = str(uuid.uuid4())
if config is None:
config = ImageConfig(
widget_class="BECImageShow",
gui_id=widget_id,
parent_id=self.gui_id,
color_map=color_map,
color_bar=color_bar,
vrange=vrange,
)
image = self.add_widget(
widget_type="ImShow",
widget_id=widget_id,
row=row,
col=col,
config=config,
**axis_kwargs,
image = self.subplot_factory(
widget_type="BECImageShow", config=config, row=row, col=col, new=new, **axis_kwargs
)
if config is not None:
return image
image = self._init_image(
image=image,
monitor=monitor,
@ -559,76 +440,100 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
)
return image
def motor_map(self, motor_x: str = None, motor_y: str = None, **axis_kwargs) -> BECMotorMap:
def motor_map(
self,
motor_x: str = None,
motor_y: str = None,
new: bool = False,
row: int | None = None,
col: int | None = None,
config: dict | None = None,
**axis_kwargs,
) -> BECMotorMap:
"""
Add a motor map to the figure. Always access the first motor map widget in the figure.
Args:
motor_x(str): The name of the motor for the X axis.
motor_y(str): The name of the motor for the Y axis.
new(bool): If True, create a new plot instead of using the first plot.
row(int): The row coordinate of the widget in the figure. If not provided, the next empty row will be used.
col(int): The column coordinate of the widget in the figure. If not provided, the next empty column will be used.
config(dict): Recreates the whole BECImageShow widget from provided configuration.
**axis_kwargs: Additional axis properties to set on the widget after creation.
Returns:
BECMotorMap: The motor map widget.
"""
motor_map = WidgetContainerUtils.find_first_widget_by_class(
self._widgets, BECMotorMap, can_fail=True
motor_map = self.subplot_factory(
widget_type="BECMotorMap", config=config, row=row, col=col, new=new, **axis_kwargs
)
if motor_map is not None:
if axis_kwargs:
motor_map.set(**axis_kwargs)
else:
motor_map = self.add_motor_map(**axis_kwargs)
if config is not None:
return motor_map
if motor_x is not None and motor_y is not None:
motor_map.change_motors(motor_x, motor_y)
return motor_map
def add_motor_map(
def subplot_factory(
self,
motor_x: str = None,
motor_y: str = None,
widget_type: Literal[
"BECPlotBase", "BECWaveform", "BECImageShow", "BECMotorMap"
] = "BECPlotBase",
row: int = None,
col: int = None,
config=None,
new: bool = False,
**axis_kwargs,
) -> BECMotorMap:
"""
Args:
motor_x(str): The name of the motor for the X axis.
motor_y(str): The name of the motor for the Y axis.
row(int): The row coordinate of the widget in the figure. If not provided, the next empty row will be used.
col(int): The column coordinate of the widget in the figure. If not provided, the next empty column will be used.
config(dict): Additional configuration for the widget.
**axis_kwargs:
Returns:
BECMotorMap: The motor map widget.
"""
widget_id = str(uuid.uuid4())
if config is None:
config = MotorMapConfig(
widget_class="BECMotorMap", gui_id=widget_id, parent_id=self.gui_id
) -> BECPlotBase:
# Case 1 - config provided, new plot, possible to define coordinates
if config is not None:
widget_cls = config["widget_class"]
if widget_cls != widget_type:
raise ValueError(
f"Widget type '{widget_type}' does not match the provided configuration ({widget_cls})."
)
widget = self.add_widget(
widget_type=widget_type, config=config, row=row, col=col, **axis_kwargs
)
motor_map = self.add_widget(
widget_type="MotorMap",
widget_id=widget_id,
row=row,
col=col,
config=config,
**axis_kwargs,
)
return widget
if motor_x is not None and motor_y is not None:
motor_map.change_motors(motor_x, motor_y)
# Case 2 - find first plot or create first plot if no plot available, no config provided, no coordinates
if new is False and (row is None or col is None):
widget = WidgetContainerUtils.find_first_widget_by_class(
self._widgets, self.subplot_map[widget_type], can_fail=True
)
if widget is not None:
if axis_kwargs:
widget.set(**axis_kwargs)
else:
widget = self.add_widget(widget_type=widget_type, **axis_kwargs)
return widget
return motor_map
# Case 3 - modifying existing plot wit coordinates provided
elif new is False and (row is not None and col is not None):
try:
widget = self.axes(row, col)
except ValueError:
widget = None
if widget is not None:
if axis_kwargs:
widget.set(**axis_kwargs)
else:
widget = self.add_widget(widget_type=widget_type, row=row, col=col, **axis_kwargs)
return widget
# Case 4 - no previous plot or new plot, no config provided, possible to define coordinates
else:
widget = self.add_widget(widget_type=widget_type, row=row, col=col, **axis_kwargs)
return widget
def add_widget(
self,
widget_type: Literal["PlotBase", "Waveform1D", "ImShow"] = "PlotBase",
widget_type: Literal[
"BECPlotBase", "BECWaveform", "BECImageShow", "BECMotorMap"
] = "BECPlotBase",
widget_id: str = None,
row: int = None,
col: int = None,
@ -659,6 +564,9 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
config=config,
**axis_kwargs,
)
# has to be changed manually to ensure unique id, if config is copied from existing widget, the id could be
# used otherwise multiple times
widget.set_gui_id(widget_id)
# Check if position is occupied
if row is not None and col is not None:

View File

@ -138,7 +138,8 @@ class BECImageShow(BECPlotBase):
self.apply_axis_config()
self._images = defaultdict(dict)
# TODO extend by adding image by config
for image_id, image_config in config.images.items():
self.add_image_by_config(image_config)
def change_gui_id(self, new_gui_id: str):
"""
@ -241,7 +242,7 @@ class BECImageShow(BECPlotBase):
f"Monitor with ID '{monitor}' already exists in widget '{self.gui_id}'."
)
monitor = self.entry_validator.validate_monitor(monitor)
# monitor = self.entry_validator.validate_monitor(monitor)
image_config = ImageItemConfig(
widget_class="BECImageItem",
@ -251,12 +252,13 @@ class BECImageShow(BECPlotBase):
downsample=downsample,
opacity=opacity,
vrange=vrange,
source=image_source,
monitor=monitor,
# post_processing=post_processing,
**kwargs,
)
image = self._add_image_object(source=image_source, name=monitor, config=image_config)
self._connect_device_monitor(monitor)
return image
def add_custom_image(
@ -290,7 +292,9 @@ class BECImageShow(BECPlotBase):
**kwargs,
)
image = self._add_image_object(source=image_source, config=image_config, data=data)
image = self._add_image_object(
source=image_source, name=name, config=image_config, data=data
)
return image
def apply_setting_to_images(
@ -516,16 +520,18 @@ class BECImageShow(BECPlotBase):
previous_monitor = image_item.config.monitor
except AttributeError:
previous_monitor = None
if previous_monitor != monitor:
if previous_monitor:
self.bec_dispatcher.disconnect_slot(
self.on_image_update, MessageEndpoints.device_monitor(previous_monitor)
)
if monitor:
self.bec_dispatcher.connect_slot(
self.on_image_update, MessageEndpoints.device_monitor(monitor)
)
image_item.set_monitor(monitor)
if previous_monitor and image_item.connected is True:
self.bec_dispatcher.disconnect_slot(
self.on_image_update, MessageEndpoints.device_monitor(previous_monitor)
)
image_item.connected = False
if monitor and image_item.connected is False:
self.entry_validator.validate_monitor(monitor)
self.bec_dispatcher.connect_slot(
self.on_image_update, MessageEndpoints.device_monitor(monitor)
)
image_item.set_monitor(monitor)
image_item.connected = True
def _add_image_object(
self, source: str, name: str, config: ImageItemConfig, data=None
@ -534,6 +540,8 @@ class BECImageShow(BECPlotBase):
image = BECImageItem(config=config, parent_image=self)
self.plot_item.addItem(image)
self._images[source][name] = image
if source == "device_monitor":
self._connect_device_monitor(config.monitor)
self.config.images[name] = config
if data is not None:
image.setImage(data)
@ -558,23 +566,6 @@ class BECImageShow(BECPlotBase):
return True
return False
def _validate_monitor(self, monitor: str, validate_bec: bool = True):
"""
Validate the monitor name.
Args:
monitor(str): The name of the monitor.
validate_bec(bool): Whether to validate the monitor name with BEC.
Returns:
bool: True if the monitor name is valid, False otherwise.
"""
if not monitor or monitor == "":
return False
if validate_bec:
return monitor in self.dev
return True
def cleanup(self):
"""
Clean up the widget.

View File

@ -78,6 +78,7 @@ class BECImageItem(BECConnector, pg.ImageItem):
self.apply_config()
if kwargs:
self.set(**kwargs)
self.connected = False
def apply_config(self):
"""

View File

@ -38,9 +38,9 @@ def test_bec_figure_add_remove_plot(bec_figure):
initial_count = len(bec_figure._widgets)
# Adding 3 widgets - 2 WaveformBase and 1 PlotBase
w0 = bec_figure.add_plot()
w1 = bec_figure.add_plot()
w2 = bec_figure.add_widget(widget_type="PlotBase")
w0 = bec_figure.plot(new=True)
w1 = bec_figure.plot(new=True)
w2 = bec_figure.add_widget(widget_type="BECPlotBase")
# Check if the widgets were added
assert len(bec_figure._widgets) == initial_count + 3
@ -75,7 +75,7 @@ def test_add_different_types_of_widgets(bec_figure):
def test_access_widgets_access_errors(bec_figure):
bec_figure.add_plot(row=0, col=0)
bec_figure.plot(row=0, col=0)
# access widget by non-existent coordinates
with pytest.raises(ValueError) as excinfo:
@ -97,18 +97,18 @@ def test_access_widgets_access_errors(bec_figure):
def test_add_plot_to_occupied_position(bec_figure):
bec_figure.add_plot(row=0, col=0)
bec_figure.plot(row=0, col=0)
with pytest.raises(ValueError) as excinfo:
bec_figure.add_plot(row=0, col=0)
bec_figure.plot(row=0, col=0, new=True)
assert "Position at row 0 and column 0 is already occupied." in str(excinfo.value)
def test_remove_plots(bec_figure):
w1 = bec_figure.add_plot(row=0, col=0)
w2 = bec_figure.add_plot(row=0, col=1)
w3 = bec_figure.add_plot(row=1, col=0)
w4 = bec_figure.add_plot(row=1, col=1)
w1 = bec_figure.plot(row=0, col=0)
w2 = bec_figure.plot(row=0, col=1)
w3 = bec_figure.plot(row=1, col=0)
w4 = bec_figure.plot(row=1, col=1)
assert bec_figure[0, 0] == w1
assert bec_figure[0, 1] == w2
@ -135,10 +135,10 @@ def test_remove_plots(bec_figure):
def test_remove_plots_by_coordinates_ints(bec_figure):
w1 = bec_figure.add_plot(row=0, col=0)
w2 = bec_figure.add_plot(row=0, col=1)
w1 = bec_figure.plot(row=0, col=0)
w2 = bec_figure.plot(row=0, col=1)
bec_figure.remove(0, 0)
bec_figure.remove(row=0, col=0)
assert w1.gui_id not in bec_figure._widgets
assert w2.gui_id in bec_figure._widgets
assert bec_figure[0, 0] == w2
@ -146,8 +146,8 @@ def test_remove_plots_by_coordinates_ints(bec_figure):
def test_remove_plots_by_coordinates_tuple(bec_figure):
w1 = bec_figure.add_plot(row=0, col=0)
w2 = bec_figure.add_plot(row=0, col=1)
w1 = bec_figure.plot(row=0, col=0)
w2 = bec_figure.plot(row=0, col=1)
bec_figure.remove(coordinates=(0, 0))
assert w1.gui_id not in bec_figure._widgets
@ -157,7 +157,7 @@ def test_remove_plots_by_coordinates_tuple(bec_figure):
def test_remove_plot_by_id_error(bec_figure):
bec_figure.add_plot(row=0, col=0)
bec_figure.plot()
with pytest.raises(ValueError) as excinfo:
bec_figure.remove(widget_id="non_existent_widget")
@ -165,7 +165,7 @@ def test_remove_plot_by_id_error(bec_figure):
def test_remove_plot_by_coordinates_error(bec_figure):
bec_figure.add_plot(row=0, col=0)
bec_figure.plot(row=0, col=0)
with pytest.raises(ValueError) as excinfo:
bec_figure.remove(0, 1)
@ -173,7 +173,7 @@ def test_remove_plot_by_coordinates_error(bec_figure):
def test_remove_plot_by_providing_nothing(bec_figure):
bec_figure.add_plot(row=0, col=0)
bec_figure.plot(row=0, col=0)
with pytest.raises(ValueError) as excinfo:
bec_figure.remove()
@ -193,10 +193,10 @@ def test_remove_plot_by_providing_nothing(bec_figure):
def test_change_layout(bec_figure):
w1 = bec_figure.add_plot(row=0, col=0)
w2 = bec_figure.add_plot(row=0, col=1)
w3 = bec_figure.add_plot(row=1, col=0)
w4 = bec_figure.add_plot(row=1, col=1)
w1 = bec_figure.plot(row=0, col=0)
w2 = bec_figure.plot(row=0, col=1)
w3 = bec_figure.plot(row=1, col=0)
w4 = bec_figure.plot(row=1, col=1)
bec_figure.change_layout(max_columns=1)
@ -216,10 +216,10 @@ def test_change_layout(bec_figure):
def test_clear_all(bec_figure):
bec_figure.add_plot(row=0, col=0)
bec_figure.add_plot(row=0, col=1)
bec_figure.add_plot(row=1, col=0)
bec_figure.add_plot(row=1, col=1)
bec_figure.plot(row=0, col=0)
bec_figure.plot(row=0, col=1)
bec_figure.plot(row=1, col=0)
bec_figure.plot(row=1, col=1)
bec_figure.clear_all()
@ -238,3 +238,26 @@ def test_shortcuts(bec_figure):
assert im.__class__ == BECImageShow
assert motor_map.config.widget_class == "BECMotorMap"
assert motor_map.__class__ == BECMotorMap
def test_plot_access_factory(bec_figure):
plt_00 = bec_figure.plot(x_name="samx", y_name="bpm4i")
plt_01 = bec_figure.plot(x_name="samx", y_name="bpm4i", row=0, col=1)
plt_10 = bec_figure.plot(new=True)
assert bec_figure.widget_list[0] == plt_00
assert bec_figure.widget_list[1] == plt_01
assert bec_figure.widget_list[2] == plt_10
assert bec_figure.axes(row=0, col=0) == plt_00
assert bec_figure.axes(row=0, col=1) == plt_01
assert bec_figure.axes(row=1, col=0) == plt_10
assert len(plt_00.curves) == 1
assert len(plt_01.curves) == 1
assert len(plt_10.curves) == 0
# update plt_00
bec_figure.plot(x_name="samx", y_name="bpm3a")
bec_figure.plot(x=[1, 2, 3], y=[1, 2, 3], row=0, col=0)
assert len(plt_00.curves) == 3

View File

@ -9,14 +9,14 @@ from .test_bec_figure import bec_figure
def test_init_plot_base(bec_figure):
plot_base = bec_figure.add_widget(widget_type="PlotBase", widget_id="test_plot")
plot_base = bec_figure.add_widget(widget_type="BECPlotBase", widget_id="test_plot")
assert plot_base is not None
assert plot_base.config.widget_class == "BECPlotBase"
assert plot_base.config.gui_id == "test_plot"
def test_plot_base_axes_by_separate_methods(bec_figure):
plot_base = bec_figure.add_widget(widget_type="PlotBase", widget_id="test_plot")
plot_base = bec_figure.add_widget(widget_type="BECPlotBase", widget_id="test_plot")
plot_base.set_title("Test Title")
plot_base.set_x_label("Test x Label")
@ -66,7 +66,7 @@ def test_plot_base_axes_by_separate_methods(bec_figure):
def test_plot_base_axes_added_by_kwargs(bec_figure):
plot_base = bec_figure.add_widget(widget_type="PlotBase", widget_id="test_plot")
plot_base = bec_figure.add_widget(widget_type="BECPlotBase", widget_id="test_plot")
plot_base.set(
title="Test Title",