From dd502e4a9cc0226c7ef60b4cf59a8b5cbb0fb6b5 Mon Sep 17 00:00:00 2001 From: kushalkolar Date: Sat, 28 Jun 2025 21:11:20 -0400 Subject: [PATCH] start separating iw plotting and array logic --- fastplotlib/widgets/image_widget/__init__.py | 1 + fastplotlib/widgets/image_widget/_array.py | 79 ++++++++++++++++++++ fastplotlib/widgets/image_widget/_widget.py | 3 +- 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 fastplotlib/widgets/image_widget/_array.py diff --git a/fastplotlib/widgets/image_widget/__init__.py b/fastplotlib/widgets/image_widget/__init__.py index 70a1aa8ae..2c217038e 100644 --- a/fastplotlib/widgets/image_widget/__init__.py +++ b/fastplotlib/widgets/image_widget/__init__.py @@ -2,6 +2,7 @@ if IMGUI: from ._widget import ImageWidget + from ._array import ImageWidgetArray else: diff --git a/fastplotlib/widgets/image_widget/_array.py b/fastplotlib/widgets/image_widget/_array.py new file mode 100644 index 000000000..bfc8c8c92 --- /dev/null +++ b/fastplotlib/widgets/image_widget/_array.py @@ -0,0 +1,79 @@ +import numpy as np +from numpy.typing import NDArray +from typing import Literal, Callable + + +class ImageWidgetArray: + def __init__( + self, + data: NDArray, + window_functions: dict = None, + frame_apply: Callable = None, + display_dims: Literal[2, 3] = 2, + dim_names: str = "tzxy", + ): + self._data = data + self._window_functions = window_functions + self._frame_apply = frame_apply + self._dim_names = dim_names + + for k in self._window_functions: + if k not in dim_names: + raise KeyError + + self._display_dims = display_dims + + @property + def data(self) -> NDArray: + return self._data + + @data.setter + def data(self, data: NDArray): + self._data = data + + @property + def window_functions(self) -> dict | None: + return self._window_functions + + @window_functions.setter + def window_functions(self, wf: dict | None): + self._window_functions = wf + + @property + def frame_apply(self, fa: Callable | None): + self._frame_apply = fa + + @frame_apply.setter + def frame_apply(self) -> Callable | None: + return self._frame_apply + + def _apply_window_functions(self, array: NDArray, key): + if self.window_functions is not None: + for dim_name in self._window_functions.keys(): + dim_index = self._dim_names.index(dim_name) + + window_size = self.window_functions[dim_name][1] + half_window_size = int((window_size - 1) / 2) + + max_bound = self._data.shape[dim_index] + + window_indices = range() + + else: + array = array[key] + + return array + + def __getitem__(self, key): + data = self._data + + + data = self._apply_window_functions(data, key) + + if self.frame_apply is not None: + data = self.frame_apply(data) + + if data.ndim != self._display_dims: + raise ValueError + + return data diff --git a/fastplotlib/widgets/image_widget/_widget.py b/fastplotlib/widgets/image_widget/_widget.py index 650097951..479e45914 100644 --- a/fastplotlib/widgets/image_widget/_widget.py +++ b/fastplotlib/widgets/image_widget/_widget.py @@ -1,4 +1,3 @@ -from copy import deepcopy from typing import Callable from warnings import warn @@ -11,6 +10,7 @@ from ...utils import calculate_figure_shape, quick_min_max from ...tools import HistogramLUTTool from ._sliders import ImageWidgetSliders +from ._array import ImageWidgetArray # Number of dimensions that represent one image/one frame @@ -289,6 +289,7 @@ def _get_n_scrollable_dims(self, curr_arr: np.ndarray, rgb: bool) -> list[int]: def __init__( self, data: np.ndarray | list[np.ndarray], + array_types: ImageWidgetArray | list[ImageWidgetArray] = ImageWidgetArray, window_funcs: dict[str, tuple[Callable, int]] = None, frame_apply: Callable | dict[int, Callable] = None, figure_shape: tuple[int, int] = None,