From 2ab12ed60abb995abc381d9330fdcf399796d9e5 Mon Sep 17 00:00:00 2001 From: wyzula-jan Date: Tue, 15 Oct 2024 12:02:09 +0200 Subject: [PATCH] feat!: ability to disable scatter from waveform & compatible crosshair with down sampling --- bec_widgets/cli/client.py | 22 +++++++++++++++++++ bec_widgets/utils/crosshair.py | 12 ++++++++-- .../widgets/figure/plots/waveform/waveform.py | 15 +++++++++++++ .../figure/plots/waveform/waveform_curve.py | 5 +++-- .../widgets/waveform/waveform_widget.py | 10 +++++++++ 5 files changed, 60 insertions(+), 4 deletions(-) diff --git a/bec_widgets/cli/client.py b/bec_widgets/cli/client.py index 93d72a61..f198d0b3 100644 --- a/bec_widgets/cli/client.py +++ b/bec_widgets/cli/client.py @@ -552,6 +552,7 @@ class BECFigure(RPCBase): def image( self, monitor: "str" = None, + monitor_type: "Literal['1d', '2d']" = "2d", color_bar: "Literal['simple', 'full']" = "full", color_map: "str" = "magma", data: "np.ndarray" = None, @@ -856,6 +857,7 @@ class BECImageShow(RPCBase): def image( self, monitor: "str", + monitor_type: "Literal['1d', '2d']" = "2d", color_map: "Optional[str]" = "magma", color_bar: "Optional[Literal['simple', 'full']]" = "full", downsample: "Optional[bool]" = True, @@ -868,6 +870,7 @@ class BECImageShow(RPCBase): Args: monitor(str): The name of the monitor to display. + monitor_type(Literal["1d","2d"]): The type of 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. @@ -1180,6 +1183,7 @@ class BECImageWidget(RPCBase): def image( self, monitor: "str", + monitor_type: "Optional[Literal['1d', '2d']]" = "2d", color_map: "Optional[str]" = "magma", color_bar: "Optional[Literal['simple', 'full']]" = "full", downsample: "Optional[bool]" = True, @@ -2096,6 +2100,15 @@ class BECWaveform(RPCBase): colormap(str, optional): Scale the colors of curves to colormap. If None, use the default color palette. """ + @rpc_call + def enable_scatter(self, enable: "bool"): + """ + Enable/Disable scatter plot on all curves. + + Args: + enable(bool): If True, enable scatter markers; if False, disable them. + """ + @rpc_call def enable_fps_monitor(self, enable: "bool" = True): """ @@ -2419,6 +2432,15 @@ class BECWaveformWidget(RPCBase): enabled(bool): If True, enable the FPS monitor. """ + @rpc_call + def enable_scatter(self, enabled: "bool"): + """ + Enable the scatter plot of the plot widget. + + Args: + enabled(bool): If True, enable the scatter plot. + """ + @rpc_call def lock_aspect_ratio(self, lock: "bool"): """ diff --git a/bec_widgets/utils/crosshair.py b/bec_widgets/utils/crosshair.py index a42768bf..d0b6ab9d 100644 --- a/bec_widgets/utils/crosshair.py +++ b/bec_widgets/utils/crosshair.py @@ -8,6 +8,14 @@ from qtpy.QtCore import QObject, Qt from qtpy.QtCore import Signal as pyqtSignal +class NonDownsamplingScatterPlotItem(pg.ScatterPlotItem): + def setDownsampling(self, ds=None, auto=None, method=None): + pass + + def setClipToView(self, state): + pass + + class Crosshair(QObject): positionChanged = pyqtSignal(tuple) positionClicked = pyqtSignal(tuple) @@ -64,7 +72,7 @@ class Crosshair(QObject): continue pen = item.opts["pen"] color = pen.color() if hasattr(pen, "color") else pg.mkColor(pen) - marker_moved = pg.ScatterPlotItem( + marker_moved = NonDownsamplingScatterPlotItem( size=10, pen=pg.mkPen(color), brush=pg.mkBrush(None) ) marker_moved.skip_auto_range = True @@ -73,7 +81,7 @@ class Crosshair(QObject): # Create glowing effect markers for clicked events for size, alpha in [(18, 64), (14, 128), (10, 255)]: - marker_clicked = pg.ScatterPlotItem( + marker_clicked = NonDownsamplingScatterPlotItem( size=size, pen=pg.mkPen(None), brush=pg.mkBrush(color.red(), color.green(), color.blue(), alpha), diff --git a/bec_widgets/widgets/figure/plots/waveform/waveform.py b/bec_widgets/widgets/figure/plots/waveform/waveform.py index 3a2a5808..9aed15a2 100644 --- a/bec_widgets/widgets/figure/plots/waveform/waveform.py +++ b/bec_widgets/widgets/figure/plots/waveform/waveform.py @@ -72,6 +72,7 @@ class BECWaveform(BECPlotBase): "set_y_lim", "set_grid", "set_colormap", + "enable_scatter", "enable_fps_monitor", "lock_aspect_ratio", "export", @@ -371,6 +372,20 @@ class BECWaveform(BECPlotBase): else: raise ValueError("Identifier must be either an integer (index) or a string (curve_id).") + def enable_scatter(self, enable: bool): + """ + Enable/Disable scatter plot on all curves. + + Args: + enable(bool): If True, enable scatter markers; if False, disable them. + """ + for curve in self.curves: + if isinstance(curve, BECCurve): + if enable: + curve.set_symbol("o") # You can choose any symbol you like + else: + curve.set_symbol(None) + def plot( self, arg1: list | np.ndarray | str | None = None, diff --git a/bec_widgets/widgets/figure/plots/waveform/waveform_curve.py b/bec_widgets/widgets/figure/plots/waveform/waveform_curve.py index 8ba3eacf..cf9b4238 100644 --- a/bec_widgets/widgets/figure/plots/waveform/waveform_curve.py +++ b/bec_widgets/widgets/figure/plots/waveform/waveform_curve.py @@ -42,7 +42,7 @@ class CurveConfig(ConnectionConfig): parent_id: Optional[str] = Field(None, description="The parent plot of the curve.") label: Optional[str] = Field(None, description="The label of the curve.") color: Optional[str | tuple] = Field(None, description="The color of the curve.") - symbol: Optional[str] = Field("o", description="The symbol of the curve.") + symbol: Optional[str | None] = Field("o", description="The symbol of the curve.") symbol_color: Optional[str | tuple] = Field( None, description="The color of the symbol of the curve." ) @@ -201,7 +201,8 @@ class BECCurve(BECConnector, pg.PlotDataItem): symbol(str): Symbol of the curve. """ self.config.symbol = symbol - self.apply_config() + self.setSymbol(symbol) + self.updateItems() def set_symbol_color(self, symbol_color: str): """ diff --git a/bec_widgets/widgets/waveform/waveform_widget.py b/bec_widgets/widgets/waveform/waveform_widget.py index 05333278..a0af221f 100644 --- a/bec_widgets/widgets/waveform/waveform_widget.py +++ b/bec_widgets/widgets/waveform/waveform_widget.py @@ -53,6 +53,7 @@ class BECWaveformWidget(BECWidget, QWidget): "set_auto_range", "set_grid", "enable_fps_monitor", + "enable_scatter", "lock_aspect_ratio", "export", "export_to_matplotlib", @@ -650,6 +651,15 @@ class BECWaveformWidget(BECWidget, QWidget): """ self.waveform.set_outer_axes(show) + def enable_scatter(self, enabled: bool): + """ + Enable the scatter plot of the plot widget. + + Args: + enabled(bool): If True, enable the scatter plot. + """ + self.waveform.enable_scatter(enabled) + def lock_aspect_ratio(self, lock: bool): """ Lock the aspect ratio of the plot widget.