From 3484507c75500dc1b1a53853ff01937ad9ad8913 Mon Sep 17 00:00:00 2001 From: wakonig_k Date: Fri, 16 May 2025 11:35:30 +0200 Subject: [PATCH] feat(plot_base): add option to specify units --- bec_widgets/widgets/plots/plot_base.py | 48 +++++++++++++++++-- .../widgets/plots/waveform/waveform.py | 10 ++-- tests/unit_tests/test_plot_base_next_gen.py | 18 +++---- 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/bec_widgets/widgets/plots/plot_base.py b/bec_widgets/widgets/plots/plot_base.py index df7fd757..d3e4ff9d 100644 --- a/bec_widgets/widgets/plots/plot_base.py +++ b/bec_widgets/widgets/plots/plot_base.py @@ -112,8 +112,10 @@ class PlotBase(BECWidget, QWidget): self.fps_label = QLabel(alignment=Qt.AlignmentFlag.AlignRight) self._user_x_label = "" self._x_label_suffix = "" + self._x_axis_units = "" self._user_y_label = "" self._y_label_suffix = "" + self._y_axis_units = "" # Plot Indicator Items self.tick_item = BECTickItem(parent=self, plot_item=self.plot_item) @@ -473,12 +475,31 @@ class PlotBase(BECWidget, QWidget): self._x_label_suffix = suffix self._apply_x_label() + @property + def x_label_units(self) -> str: + """ + The units of the x-axis. + """ + return self._x_axis_units + + @x_label_units.setter + def x_label_units(self, units: str): + """ + The units of the x-axis. + + Args: + units(str): The units to set. + """ + self._x_axis_units = units + self._apply_x_label() + @property def x_label_combined(self) -> str: """ - The final label shown on the axis = user portion + suffix. + The final label shown on the axis = user portion + suffix + [units]. """ - return self._user_x_label + self._x_label_suffix + units = f" [{self._x_axis_units}]" if self._x_axis_units else "" + return self._user_x_label + self._x_label_suffix + units def _apply_x_label(self): """ @@ -521,12 +542,31 @@ class PlotBase(BECWidget, QWidget): self._y_label_suffix = suffix self._apply_y_label() + @property + def y_label_units(self) -> str: + """ + The units of the y-axis. + """ + return self._y_axis_units + + @y_label_units.setter + def y_label_units(self, units: str): + """ + The units of the y-axis. + + Args: + units(str): The units to set. + """ + self._y_axis_units = units + self._apply_y_label() + @property def y_label_combined(self) -> str: """ - The final y label shown on the axis = user portion + suffix. + The final y label shown on the axis = user portion + suffix + [units]. """ - return self._user_y_label + self._y_label_suffix + units = f" [{self._y_axis_units}]" if self._y_axis_units else "" + return self._user_y_label + self._y_label_suffix + units def _apply_y_label(self): """ diff --git a/bec_widgets/widgets/plots/waveform/waveform.py b/bec_widgets/widgets/plots/waveform/waveform.py index 041e3599..ce081672 100644 --- a/bec_widgets/widgets/plots/waveform/waveform.py +++ b/bec_widgets/widgets/plots/waveform/waveform.py @@ -1468,7 +1468,7 @@ class Waveform(PlotBase): x_data = data.get(x_name, {}).get(x_entry, {}).get(access_key, [0]) else: # history data x_data = data.get(x_name, {}).get(x_entry, {}).read().get("value", [0]) - new_suffix = f" [custom: {x_name}-{x_entry}]" + new_suffix = f" (custom: {x_name}-{x_entry})" # 2 User wants timestamp if self.x_axis_mode["name"] == "timestamp": @@ -1477,19 +1477,19 @@ class Waveform(PlotBase): else: # history data timestamps = data[device_name][device_entry].read().get("timestamp", [0]) x_data = timestamps - new_suffix = " [timestamp]" + new_suffix = " (timestamp)" # 3 User wants index if self.x_axis_mode["name"] == "index": x_data = None - new_suffix = " [index]" + new_suffix = " (index)" # 4 Best effort automatic mode if self.x_axis_mode["name"] is None or self.x_axis_mode["name"] == "auto": # 4.1 If there are async curves, use index if len(self._async_curves) > 0: x_data = None - new_suffix = " [auto: index]" + new_suffix = " (auto: index)" # 4.2 If there are sync curves, use the first device from the scan report else: try: @@ -1503,7 +1503,7 @@ class Waveform(PlotBase): x_data = data.get(x_name, {}).get(x_entry, {}).get(access_key, None) else: x_data = data.get(x_name, {}).get(x_entry, {}).read().get("value", None) - new_suffix = f" [auto: {x_name}-{x_entry}]" + new_suffix = f" (auto: {x_name}-{x_entry})" self._update_x_label_suffix(new_suffix) return x_data diff --git a/tests/unit_tests/test_plot_base_next_gen.py b/tests/unit_tests/test_plot_base_next_gen.py index db8386da..1e291d15 100644 --- a/tests/unit_tests/test_plot_base_next_gen.py +++ b/tests/unit_tests/test_plot_base_next_gen.py @@ -51,10 +51,11 @@ def test_set_x_label_emits_signal(qtbot, mocked_client): """ pb = create_widget(qtbot, PlotBase, client=mocked_client) with qtbot.waitSignal(pb.property_changed, timeout=500) as signal: - pb.x_label = "Voltage (V)" - assert signal.args == ["x_label", "Voltage (V)"] - assert pb.x_label == "Voltage (V)" - assert pb.plot_item.getAxis("bottom").labelText == "Voltage (V)" + pb.x_label = "Voltage" + assert signal.args == ["x_label", "Voltage"] + assert pb.x_label == "Voltage" + pb.x_label_units = "V" + assert pb.plot_item.getAxis("bottom").labelText == "Voltage [V]" def test_set_y_label_emits_signal(qtbot, mocked_client): @@ -63,10 +64,11 @@ def test_set_y_label_emits_signal(qtbot, mocked_client): """ pb = create_widget(qtbot, PlotBase, client=mocked_client) with qtbot.waitSignal(pb.property_changed, timeout=500) as signal: - pb.y_label = "Current (A)" - assert signal.args == ["y_label", "Current (A)"] - assert pb.y_label == "Current (A)" - assert pb.plot_item.getAxis("left").labelText == "Current (A)" + pb.y_label = "Current" + assert signal.args == ["y_label", "Current"] + assert pb.y_label == "Current" + pb.y_label_units = "A" + assert pb.plot_item.getAxis("left").labelText == "Current [A]" def test_set_x_min_max(qtbot, mocked_client):