bec-widgets 0.83.1__py3-none-any.whl → 0.84.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## v0.84.0 (2024-07-15)
4
+
5
+ ### Feature
6
+
7
+ * feat(waveform): async readback update implemented for async devices ([`0c6a9f2`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0c6a9f2310df31ddcd68050a17cfbf52c3e2e226))
8
+
9
+ * feat(waveform): data are taken directly from ScanItem which is defined from scan_status endpoint; scan update is triggered from scan_segment; plots can be added just specifying y_name -> best effort for setting x reported device ([`b8717f1`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/b8717f13276734dd655ab03cd6005985ad5af9fb))
10
+
11
+ ### Fix
12
+
13
+ * fix(waveform): timestamp are not converted to human readable format ([`e495fd3`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e495fd30c4c16474689943c7263e3060cb09ffb4))
14
+
15
+ * fix(waveform): set_x method various bugs fixed ([`8516a1d`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/8516a1d639925a877f174fa13f427a71131cc918))
16
+
17
+ * fix(waveform): x axis switching logic fixed when axis are not compatible ([`e4e1a90`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e4e1a905d19def22f970b364c18c953f00e10389))
18
+
19
+ * fix(waveform): dap leaked RID for all daps in current process; dap RID is now f"{scan_id}-{gui_id}" to distinguish for each plot instance ([`d23fd8b`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/d23fd8bd074ede6e14eb8e85e025cbced4bd45ef))
20
+
21
+ * fix(waveform): only one type of x axis allowed; x mode validated ([`9d6ae87`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/9d6ae87d0f03ca227570fcca8af2d8190828d271))
22
+
23
+ * fix(waveform): data for axis are taken by separate method; validation consolidated ([`fc5a8bd`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/fc5a8bdd8b260f5e9b59ec71a4610c57442e43fe))
24
+
25
+ * fix(bec_dispatcher): connect_slot can accept kwargs ([`0aa317a`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/0aa317aae58d3612d46f05b85f8b0db3d12bbe14))
26
+
27
+ ### Refactor
28
+
29
+ * refactor(waveform): plot can be prompted without specifying kwargs ([`48911e9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/48911e934815923c94edb5ced6042058a11a97f5))
30
+
31
+ * refactor(jupyter_console_window): added more examples of waveforms ([`fc935d9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/fc935d9fc81067c3a67389ff88ea97da2e0c903e))
32
+
33
+ ### Test
34
+
35
+ * test(waveform): tests extended ([`006992e`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/006992e43cc56d56261bc4fd3e9cae9abcab2153))
36
+
3
37
  ## v0.83.1 (2024-07-14)
4
38
 
5
39
  ### Fix
@@ -105,39 +139,3 @@
105
139
  * feat(color_button): can get colors in RGBA or HEX ([`9594be2`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/9594be260680d11c8550ff74ffb8d679e5a5b8f6))
106
140
 
107
141
  ## v0.80.1 (2024-07-06)
108
-
109
- ### Fix
110
-
111
- * fix(entry_validator): check for entry == "" ([`61de7e9`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/61de7e9e221c766b9fb3ec23246da6a11c96a986))
112
-
113
- ## v0.80.0 (2024-07-06)
114
-
115
- ### Feature
116
-
117
- * feat(qt5): dropped support for qt5; pyside2 and pyqt5 ([`fadbf77`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/fadbf77866903beff6580802bc203d53367fc7e7))
118
-
119
- * feat(plugins): moved plugin dict to dataclass and container ([`03819a3`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/03819a3d902b4a51f3e882d52aedd971b2a8e127))
120
-
121
- * feat(plugins): added support for pyqt6 ui files ([`d6d0777`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/d6d07771135335cb78dc648508ce573b8970261a))
122
-
123
- * feat(plugins): added bec widgets base class ([`1aa83e0`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/1aa83e0ef1ffe45b01677b0b4590535cb0ca1cff))
124
-
125
- ## v0.79.3 (2024-07-05)
126
-
127
- ### Fix
128
-
129
- * fix: changed inheritance to adress qt designer bug in rendering ([`e403870`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/e403870874bd5e45840a034d6f1b3dd576d9c846))
130
-
131
- * fix: add designer plugin classes ([`1586ce2`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/1586ce2d6cba2bb086b2ef596e724bb9e40ab4f2))
132
-
133
- ### Refactor
134
-
135
- * refactor: simplify logic in bec_status_box ([`576353c`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/576353cfe8c6fd64db561f0b6e2bc951300643d3))
136
-
137
- ## v0.79.2 (2024-07-04)
138
-
139
- ### Fix
140
-
141
- * fix: overwrite closeEvent and call super class ([`bc0ef78`](https://gitlab.psi.ch/bec/bec_widgets/-/commit/bc0ef7893ef100b71b62101c459655509b534a56))
142
-
143
- ## v0.79.1 (2024-07-03)
PKG-INFO CHANGED
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bec_widgets
3
- Version: 0.83.1
3
+ Version: 0.84.0
4
4
  Summary: BEC Widgets
5
5
  Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec_widgets/issues
6
6
  Project-URL: Homepage, https://gitlab.psi.ch/bec/bec_widgets
bec_widgets/cli/client.py CHANGED
@@ -19,6 +19,9 @@ class Widgets(str, enum.Enum):
19
19
  BECMotorMapWidget = "BECMotorMapWidget"
20
20
  BECQueue = "BECQueue"
21
21
  BECStatusBox = "BECStatusBox"
22
+ DeviceBox = "DeviceBox"
23
+ DeviceComboBox = "DeviceComboBox"
24
+ DeviceLineEdit = "DeviceLineEdit"
22
25
  RingProgressBar = "RingProgressBar"
23
26
  ScanControl = "ScanControl"
24
27
  StopButton = "StopButton"
@@ -465,8 +468,9 @@ class BECFigure(RPCBase):
465
468
  @rpc_call
466
469
  def plot(
467
470
  self,
468
- x: "list | np.ndarray | None" = None,
471
+ arg1: "list | np.ndarray | str | None" = None,
469
472
  y: "list | np.ndarray | None" = None,
473
+ x: "list | np.ndarray | None" = None,
470
474
  x_name: "str | None" = None,
471
475
  y_name: "str | None" = None,
472
476
  z_name: "str | None" = None,
@@ -488,8 +492,9 @@ class BECFigure(RPCBase):
488
492
  Add a 1D waveform plot to the figure. Always access the first waveform widget in the figure.
489
493
 
490
494
  Args:
491
- x(list | np.ndarray): Custom x data to plot.
495
+ arg1(list | np.ndarray | str | None): First argument which can be x data, y data, or y_name.
492
496
  y(list | np.ndarray): Custom y data to plot.
497
+ x(list | np.ndarray): Custom x data to plot.
493
498
  x_name(str): The name of the device for the x-axis.
494
499
  y_name(str): The name of the device for the y-axis.
495
500
  z_name(str): The name of the device for the z-axis.
@@ -1494,8 +1499,9 @@ class BECWaveform(RPCBase):
1494
1499
  @rpc_call
1495
1500
  def plot(
1496
1501
  self,
1497
- x: "list | np.ndarray | None" = None,
1502
+ arg1: "list | np.ndarray | str | None" = None,
1498
1503
  y: "list | np.ndarray | None" = None,
1504
+ x: "list | np.ndarray | None" = None,
1499
1505
  x_name: "str | None" = None,
1500
1506
  y_name: "str | None" = None,
1501
1507
  z_name: "str | None" = None,
@@ -1507,13 +1513,20 @@ class BECWaveform(RPCBase):
1507
1513
  label: "str | None" = None,
1508
1514
  validate: "bool" = True,
1509
1515
  dap: "str | None" = None,
1516
+ **kwargs,
1510
1517
  ) -> "BECCurve":
1511
1518
  """
1512
1519
  Plot a curve to the plot widget.
1520
+
1513
1521
  Args:
1514
- x(list | np.ndarray): Custom x data to plot.
1522
+ arg1(list | np.ndarray | str | None): First argument which can be x data, y data, or y_name.
1515
1523
  y(list | np.ndarray): Custom y data to plot.
1516
- x_name(str): The name of the device for the x-axis.
1524
+ x(list | np.ndarray): Custom y data to plot.
1525
+ x_name(str): Name of the x signal.
1526
+ - "best_effort": Use the best effort signal.
1527
+ - "timestamp": Use the timestamp signal.
1528
+ - "index": Use the index signal.
1529
+ - Custom signal name of device from BEC.
1517
1530
  y_name(str): The name of the device for the y-axis.
1518
1531
  z_name(str): The name of the device for the z-axis.
1519
1532
  x_entry(str): The name of the entry for the x-axis.
@@ -1523,7 +1536,7 @@ class BECWaveform(RPCBase):
1523
1536
  color_map_z(str): The color map to use for the z-axis.
1524
1537
  label(str): The label of the curve.
1525
1538
  validate(bool): If True, validate the device names and entries.
1526
- dap(str): The dap model to use for the curve. If not specified, none will be added.
1539
+ dap(str): The dap model to use for the curve, only available for sync devices. If not specified, none will be added.
1527
1540
 
1528
1541
  Returns:
1529
1542
  BECCurve: The curve object.
@@ -1532,12 +1545,13 @@ class BECWaveform(RPCBase):
1532
1545
  @rpc_call
1533
1546
  def add_dap(
1534
1547
  self,
1535
- x_name: "str",
1536
- y_name: "str",
1548
+ x_name: "str | None" = None,
1549
+ y_name: "str | None" = None,
1537
1550
  x_entry: "Optional[str]" = None,
1538
1551
  y_entry: "Optional[str]" = None,
1539
1552
  color: "Optional[str]" = None,
1540
1553
  dap: "str" = "GaussianModel",
1554
+ validate_bec: "bool" = True,
1541
1555
  **kwargs,
1542
1556
  ) -> "BECCurve":
1543
1557
  """
@@ -1552,12 +1566,27 @@ class BECWaveform(RPCBase):
1552
1566
  color_map_z(str): The color map to use for the z-axis.
1553
1567
  label(str, optional): Label of the curve. Defaults to None.
1554
1568
  dap(str): The dap model to use for the curve.
1569
+ validate_bec(bool, optional): If True, validate the signal with BEC. Defaults to True.
1555
1570
  **kwargs: Additional keyword arguments for the curve configuration.
1556
1571
 
1557
1572
  Returns:
1558
1573
  BECCurve: The curve object.
1559
1574
  """
1560
1575
 
1576
+ @rpc_call
1577
+ def set_x(self, x_name: "str", x_entry: "str | None" = None):
1578
+ """
1579
+ Change the x axis of the plot widget.
1580
+
1581
+ Args:
1582
+ x_name(str): Name of the x signal.
1583
+ - "best_effort": Use the best effort signal.
1584
+ - "timestamp": Use the timestamp signal.
1585
+ - "index": Use the index signal.
1586
+ - Custom signal name of device from BEC.
1587
+ x_entry(str): Entry of the x signal.
1588
+ """
1589
+
1561
1590
  @rpc_call
1562
1591
  def get_dap_params(self) -> "dict":
1563
1592
  """
@@ -1742,6 +1771,12 @@ class BECWaveform(RPCBase):
1742
1771
  Remove the plot widget from the figure.
1743
1772
  """
1744
1773
 
1774
+ @rpc_call
1775
+ def clear_all(self):
1776
+ """
1777
+ None
1778
+ """
1779
+
1745
1780
  @rpc_call
1746
1781
  def set_legend_label_size(self, size: "int" = None):
1747
1782
  """
@@ -1752,6 +1787,24 @@ class BECWaveform(RPCBase):
1752
1787
  """
1753
1788
 
1754
1789
 
1790
+ class DeviceBox(RPCBase):
1791
+ @property
1792
+ @rpc_call
1793
+ def _config_dict(self) -> "dict":
1794
+ """
1795
+ Get the configuration of the widget.
1796
+
1797
+ Returns:
1798
+ dict: The configuration of the widget.
1799
+ """
1800
+
1801
+ @rpc_call
1802
+ def _get_all_rpc(self) -> "dict":
1803
+ """
1804
+ Get all registered RPC objects.
1805
+ """
1806
+
1807
+
1755
1808
  class DeviceComboBox(RPCBase):
1756
1809
  @property
1757
1810
  @rpc_call
@@ -2,13 +2,19 @@ import os
2
2
 
3
3
  import numpy as np
4
4
  import pyqtgraph as pg
5
- from qtconsole.inprocess import QtInProcessKernelManager
6
- from qtconsole.rich_jupyter_widget import RichJupyterWidget
7
5
  from qtpy.QtCore import QSize
8
6
  from qtpy.QtGui import QIcon
9
- from qtpy.QtWidgets import QApplication, QVBoxLayout, QWidget
10
-
11
- from bec_widgets.utils import BECDispatcher, UILoader
7
+ from qtpy.QtWidgets import (
8
+ QApplication,
9
+ QGroupBox,
10
+ QHBoxLayout,
11
+ QSplitter,
12
+ QTabWidget,
13
+ QVBoxLayout,
14
+ QWidget,
15
+ )
16
+
17
+ from bec_widgets.utils import BECDispatcher
12
18
  from bec_widgets.utils.colors import apply_theme
13
19
  from bec_widgets.widgets.dock.dock_area import BECDockArea
14
20
  from bec_widgets.widgets.figure import BECFigure
@@ -21,14 +27,8 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
21
27
  def __init__(self, parent=None):
22
28
  super().__init__(parent)
23
29
 
24
- current_path = os.path.dirname(__file__)
25
- self.ui = UILoader().load_ui(os.path.join(current_path, "jupyter_console_window.ui"), self)
26
-
27
30
  self._init_ui()
28
31
 
29
- self.ui.splitter.setSizes([200, 100])
30
- self.safe_close = False
31
-
32
32
  # console push
33
33
  if self.console.inprocess is True:
34
34
  self.console.kernel_manager.kernel.shell.push(
@@ -40,10 +40,12 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
40
40
  "w1": self.w1,
41
41
  "w2": self.w2,
42
42
  "w3": self.w3,
43
- "w1_c": self.w1_c,
44
- "w2_c": self.w2_c,
45
- "w3_c": self.w3_c,
46
43
  "w4": self.w4,
44
+ "w5": self.w5,
45
+ "w6": self.w6,
46
+ "w7": self.w7,
47
+ "w8": self.w8,
48
+ "w9": self.w9,
47
49
  "d0": self.d0,
48
50
  "d1": self.d1,
49
51
  "d2": self.d2,
@@ -53,14 +55,30 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
53
55
  )
54
56
 
55
57
  def _init_ui(self):
56
- # Plotting window
57
- self.glw_1_layout = QVBoxLayout(self.ui.glw) # Create a new QVBoxLayout
58
- self.figure = BECFigure(parent=self, gui_id="remote") # Create a new BECDeviceMonitor
59
- self.glw_1_layout.addWidget(self.figure) # Add BECDeviceMonitor to the layout
58
+ self.layout = QHBoxLayout(self)
59
+
60
+ # Horizontal splitter
61
+ splitter = QSplitter(self)
62
+ self.layout.addWidget(splitter)
60
63
 
61
- self.dock_layout = QVBoxLayout(self.ui.dock_placeholder)
62
- self.dock = BECDockArea(gui_id="remote")
63
- self.dock_layout.addWidget(self.dock)
64
+ tab_widget = QTabWidget(splitter)
65
+
66
+ first_tab = QWidget()
67
+ first_tab_layout = QVBoxLayout(first_tab)
68
+ self.dock = BECDockArea(gui_id="dock")
69
+ first_tab_layout.addWidget(self.dock)
70
+ tab_widget.addTab(first_tab, "Dock Area")
71
+
72
+ second_tab = QWidget()
73
+ second_tab_layout = QVBoxLayout(second_tab)
74
+ self.figure = BECFigure(parent=self, gui_id="figure")
75
+ second_tab_layout.addWidget(self.figure)
76
+ tab_widget.addTab(second_tab, "BEC Figure")
77
+
78
+ group_box = QGroupBox("Jupyter Console", splitter)
79
+ group_box_layout = QVBoxLayout(group_box)
80
+ self.console = BECJupyterConsole(inprocess=True)
81
+ group_box_layout.addWidget(self.console)
64
82
 
65
83
  # add stuff to figure
66
84
  self._init_figure()
@@ -68,44 +86,70 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
68
86
  # init dock for testing
69
87
  self._init_dock()
70
88
 
71
- self.console_layout = QVBoxLayout(self.ui.widget_console)
72
- self.console = BECJupyterConsole(inprocess=True)
73
- self.console_layout.addWidget(self.console)
89
+ self.setWindowTitle("Jupyter Console Window")
74
90
 
75
91
  def _init_figure(self):
76
- self.figure.plot(x_name="samx", y_name="samy", z_name="bpm4i", color_map_z="cividis")
77
- self.figure.motor_map("samx", "samy")
78
- self.figure.image("eiger", color_map="viridis", vrange=(0, 100))
79
- self.figure.plot(
80
- x_name="samx", y_name="samy", z_name="bpm4i", color_map_z="magma", new=True
92
+ self.w1 = self.figure.plot(
93
+ x_name="samx",
94
+ y_name="bpm4i",
95
+ # title="Standard Plot with sync device, custom labels - w1",
96
+ # x_label="Motor Position",
97
+ # y_label="Intensity (A.U.)",
98
+ row=0,
99
+ col=0,
100
+ )
101
+ self.w1.set(
102
+ title="Standard Plot with sync device, custom labels - w1",
103
+ x_label="Motor Position",
104
+ y_label="Intensity (A.U.)",
105
+ )
106
+ self.w2 = self.figure.motor_map("samx", "samy", row=0, col=1)
107
+ self.w3 = self.figure.image(
108
+ "eiger", color_map="viridis", vrange=(0, 100), title="Eiger Image - w3", row=0, col=2
109
+ )
110
+ self.w4 = self.figure.plot(
111
+ x_name="samx",
112
+ y_name="samy",
113
+ z_name="bpm4i",
114
+ color_map_z="magma",
115
+ new=True,
116
+ title="2D scatter plot - w4",
117
+ row=0,
118
+ col=3,
119
+ )
120
+ self.w5 = self.figure.plot(
121
+ y_name="bpm4i",
122
+ new=True,
123
+ title="Best Effort Plot - w5",
124
+ dap="GaussianModel",
125
+ row=1,
126
+ col=0,
127
+ )
128
+ self.w6 = self.figure.plot(
129
+ x_name="timestamp", y_name="bpm4i", new=True, title="Timestamp Plot - w6", row=1, col=1
130
+ )
131
+ self.w7 = self.figure.plot(
132
+ x_name="index", y_name="bpm4i", new=True, title="Index Plot - w7", row=1, col=2
133
+ )
134
+ self.w8 = self.figure.plot(
135
+ y_name="monitor_async", new=True, title="Async Plot - Best Effort - w8", row=2, col=0
136
+ )
137
+ self.w9 = self.figure.plot(
138
+ x_name="timestamp",
139
+ y_name="monitor_async",
140
+ new=True,
141
+ title="Async Plot - timestamp - w9",
142
+ row=2,
143
+ col=1,
144
+ )
145
+ self.w10 = self.figure.plot(
146
+ x_name="index",
147
+ y_name="monitor_async",
148
+ new=True,
149
+ title="Async Plot - index - w10",
150
+ row=2,
151
+ col=2,
81
152
  )
82
-
83
- self.figure.change_layout(2, 2)
84
-
85
- self.w1 = self.figure[0, 0]
86
- self.w2 = self.figure[0, 1]
87
- self.w3 = self.figure[1, 0]
88
- self.w4 = self.figure[1, 1]
89
-
90
- # Plot Customisation
91
- self.w1.set_title("Waveform 1")
92
- self.w1.set_x_label("Motor Position (samx)")
93
- self.w1.set_y_label("Intensity A.U.")
94
-
95
- # Image Customisation
96
- self.w3.set_title("Eiger Image")
97
- self.w3.set_x_label("X")
98
- self.w3.set_y_label("Y")
99
-
100
- # Configs to try to pass
101
- self.w1_c = self.w1._config_dict
102
- self.w2_c = self.w2._config_dict
103
- self.w3_c = self.w3._config_dict
104
-
105
- # curves for w1
106
- self.c1 = self.w1.get_config()
107
-
108
- self.fig_c = self.figure._config_dict
109
153
 
110
154
  def _init_dock(self):
111
155
 
@@ -131,9 +175,13 @@ class JupyterConsoleWindow(QWidget): # pragma: no cover:
131
175
 
132
176
  def closeEvent(self, event):
133
177
  """Override to handle things when main window is closed."""
178
+ self.dock.clear_all()
134
179
  self.dock.cleanup()
180
+ self.dock.close()
135
181
  self.figure.clear_all()
136
- self.figure.client.shutdown()
182
+ self.figure.cleanup()
183
+ self.figure.close()
184
+
137
185
  super().closeEvent(event)
138
186
 
139
187
 
@@ -134,7 +134,10 @@ class BECDispatcher:
134
134
  cls.qapp = None
135
135
 
136
136
  def connect_slot(
137
- self, slot: Callable, topics: Union[EndpointInfo, str, list[Union[EndpointInfo, str]]]
137
+ self,
138
+ slot: Callable,
139
+ topics: Union[EndpointInfo, str, list[Union[EndpointInfo, str]]],
140
+ **kwargs,
138
141
  ) -> None:
139
142
  """Connect widget's pyqt slot, so that it is called on new pub/sub topic message.
140
143
 
@@ -144,7 +147,7 @@ class BECDispatcher:
144
147
  topics (EndpointInfo | str | list): A topic or list of topics that can typically be acquired via bec_lib.MessageEndpoints
145
148
  """
146
149
  slot = QtThreadSafeCallback(slot)
147
- self.client.connector.register(topics, cb=slot)
150
+ self.client.connector.register(topics, cb=slot, **kwargs)
148
151
  topics_str, _ = self.client.connector._convert_endpointinfo(topics)
149
152
  self._slots[slot].update(set(topics_str))
150
153
 
@@ -227,106 +227,12 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
227
227
  """
228
228
  self._widgets = value
229
229
 
230
- def _init_waveform(
231
- self,
232
- waveform,
233
- x_name: str = None,
234
- y_name: str = None,
235
- z_name: str = None,
236
- x_entry: str = None,
237
- y_entry: str = None,
238
- z_entry: str = None,
239
- x: list | np.ndarray = None,
240
- y: list | np.ndarray = None,
241
- color: str | None = None,
242
- color_map_z: str | None = "plasma",
243
- label: str | None = None,
244
- validate: bool = True,
245
- dap: str | None = None,
246
- ) -> BECWaveform:
247
- """
248
- Configure the waveform based on the provided parameters.
249
-
250
- Args:
251
- waveform (BECWaveform): The waveform to configure.
252
- x (list | np.ndarray): Custom x data to plot.
253
- y (list | np.ndarray): Custom y data to plot.
254
- x_name (str): The name of the device for the x-axis.
255
- y_name (str): The name of the device for the y-axis.
256
- z_name (str): The name of the device for the z-axis.
257
- x_entry (str): The name of the entry for the x-axis.
258
- y_entry (str): The name of the entry for the y-axis.
259
- z_entry (str): The name of the entry for the z-axis.
260
- color (str): The color of the curve.
261
- color_map_z (str): The color map to use for the z-axis.
262
- label (str): The label of the curve.
263
- validate (bool): If True, validate the device names and entries.
264
- dap (str): The DAP model to use for the curve.
265
- """
266
- if x is not None and y is None:
267
- if isinstance(x, np.ndarray):
268
- if x.ndim == 1:
269
- y = np.arange(x.size)
270
- waveform.add_curve_custom(x=np.arange(x.size), y=x, color=color, label=label)
271
- return waveform
272
- if x.ndim == 2:
273
- waveform.add_curve_custom(x=x[:, 0], y=x[:, 1], color=color, label=label)
274
- return waveform
275
- elif isinstance(x, list):
276
- y = np.arange(len(x))
277
- waveform.add_curve_custom(x=np.arange(len(x)), y=x, color=color, label=label)
278
- return waveform
279
- else:
280
- raise ValueError(
281
- "Invalid input. Provide either device names (x_name, y_name) or custom data."
282
- )
283
- if x is not None and y is not None:
284
- waveform.add_curve_custom(x=x, y=y, color=color, label=label)
285
- return waveform
286
- # User wants to add scan curve -> 1D Waveform
287
- 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:
288
- waveform.plot(
289
- x_name=x_name,
290
- y_name=y_name,
291
- x_entry=x_entry,
292
- y_entry=y_entry,
293
- validate=validate,
294
- color=color,
295
- label=label,
296
- dap=dap,
297
- )
298
- # User wants to add scan curve -> 2D Waveform Scatter
299
- if (
300
- x_name is not None
301
- and y_name is not None
302
- and z_name is not None
303
- and x is None
304
- and y is None
305
- ):
306
- waveform.plot(
307
- x_name=x_name,
308
- y_name=y_name,
309
- z_name=z_name,
310
- x_entry=x_entry,
311
- y_entry=y_entry,
312
- z_entry=z_entry,
313
- color=color,
314
- color_map_z=color_map_z,
315
- label=label,
316
- validate=validate,
317
- dap=dap,
318
- )
319
- # User wants to add custom curve
320
- elif x is not None and y is not None and x_name is None and y_name is None:
321
- waveform.add_curve_custom(x=x, y=y, color=color, label=label)
322
-
323
- return waveform
324
-
325
230
  @typechecked
326
231
  def plot(
327
232
  self,
328
- x: list | np.ndarray | None = None,
233
+ arg1: list | np.ndarray | str | None = None,
329
234
  y: list | np.ndarray | None = None,
235
+ x: list | np.ndarray | None = None,
330
236
  x_name: str | None = None,
331
237
  y_name: str | None = None,
332
238
  z_name: str | None = None,
@@ -348,8 +254,9 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
348
254
  Add a 1D waveform plot to the figure. Always access the first waveform widget in the figure.
349
255
 
350
256
  Args:
351
- x(list | np.ndarray): Custom x data to plot.
257
+ arg1(list | np.ndarray | str | None): First argument which can be x data, y data, or y_name.
352
258
  y(list | np.ndarray): Custom y data to plot.
259
+ x(list | np.ndarray): Custom x data to plot.
353
260
  x_name(str): The name of the device for the x-axis.
354
261
  y_name(str): The name of the device for the y-axis.
355
262
  z_name(str): The name of the device for the z-axis.
@@ -376,23 +283,23 @@ class BECFigure(BECConnector, pg.GraphicsLayoutWidget):
376
283
  if config is not None:
377
284
  return waveform
378
285
 
379
- # Passing args to init_waveform
380
- waveform = self._init_waveform(
381
- waveform=waveform,
382
- x=x,
383
- y=y,
384
- x_name=x_name,
385
- y_name=y_name,
386
- z_name=z_name,
387
- x_entry=x_entry,
388
- y_entry=y_entry,
389
- z_entry=z_entry,
390
- color=color,
391
- color_map_z=color_map_z,
392
- label=label,
393
- validate=validate,
394
- dap=dap,
395
- )
286
+ if arg1 is not None or y_name is not None or (y is not None and x is not None):
287
+ waveform.plot(
288
+ arg1=arg1,
289
+ y=y,
290
+ x=x,
291
+ x_name=x_name,
292
+ y_name=y_name,
293
+ z_name=z_name,
294
+ x_entry=x_entry,
295
+ y_entry=y_entry,
296
+ z_entry=z_entry,
297
+ color=color,
298
+ color_map_z=color_map_z,
299
+ label=label,
300
+ validate=validate,
301
+ dap=dap,
302
+ )
396
303
  return waveform
397
304
 
398
305
  def _init_image(