From dba5a00b3dbf4138d9daaa91df28668ac9a7a3a5 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Tue, 13 Jun 2023 12:54:55 +0100 Subject: [PATCH 01/12] Start a features mixin class --- src/napari_matplotlib/features.py | 21 +++++++++++++++++++++ src/napari_matplotlib/scatter.py | 13 ++----------- 2 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 src/napari_matplotlib/features.py diff --git a/src/napari_matplotlib/features.py b/src/napari_matplotlib/features.py new file mode 100644 index 00000000..0f572ec0 --- /dev/null +++ b/src/napari_matplotlib/features.py @@ -0,0 +1,21 @@ +import napari.layers + +from napari_matplotlib.base import NapariMPLWidget +from napari_matplotlib.util import Interval + + +class FeaturesMixin(NapariMPLWidget): + """ + Mixin to help with widgets that plot data from a features table stored + on a single layer. + """ + + n_layers_input = Interval(1, 1) + # All layers that have a .features attributes + input_layer_types = ( + napari.layers.Labels, + napari.layers.Points, + napari.layers.Shapes, + napari.layers.Tracks, + napari.layers.Vectors, + ) diff --git a/src/napari_matplotlib/scatter.py b/src/napari_matplotlib/scatter.py index 334f941c..4f69fa78 100644 --- a/src/napari_matplotlib/scatter.py +++ b/src/napari_matplotlib/scatter.py @@ -5,6 +5,7 @@ from qtpy.QtWidgets import QComboBox, QLabel, QVBoxLayout, QWidget from .base import SingleAxesWidget +from .features import FeaturesMixin from .util import Interval __all__ = ["ScatterBaseWidget", "ScatterWidget", "FeaturesScatterWidget"] @@ -85,21 +86,11 @@ def _get_data(self) -> Tuple[npt.NDArray[Any], npt.NDArray[Any], str, str]: return x, y, x_axis_name, y_axis_name -class FeaturesScatterWidget(ScatterBaseWidget): +class FeaturesScatterWidget(ScatterBaseWidget, FeaturesMixin): """ Widget to scatter data stored in two layer feature attributes. """ - n_layers_input = Interval(1, 1) - # All layers that have a .features attributes - input_layer_types = ( - napari.layers.Labels, - napari.layers.Points, - napari.layers.Shapes, - napari.layers.Tracks, - napari.layers.Vectors, - ) - def __init__( self, napari_viewer: napari.viewer.Viewer, From 5702ed9da4d07bf0efdef13081cc41e4fc0773dc Mon Sep 17 00:00:00 2001 From: David Stansby Date: Tue, 13 Jun 2023 12:58:07 +0100 Subject: [PATCH 02/12] Move get_valid_axis_keys --- src/napari_matplotlib/features.py | 17 +++++++++++++++++ src/napari_matplotlib/scatter.py | 17 +---------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/napari_matplotlib/features.py b/src/napari_matplotlib/features.py index 0f572ec0..f55592c2 100644 --- a/src/napari_matplotlib/features.py +++ b/src/napari_matplotlib/features.py @@ -1,3 +1,5 @@ +from typing import List + import napari.layers from napari_matplotlib.base import NapariMPLWidget @@ -19,3 +21,18 @@ class FeaturesMixin(NapariMPLWidget): napari.layers.Tracks, napari.layers.Vectors, ) + + def _get_valid_axis_keys(self) -> List[str]: + """ + Get the valid axis keys from the layer FeatureTable. + + Returns + ------- + axis_keys : List[str] + The valid axis keys in the FeatureTable. If the table is empty + or there isn't a table, returns an empty list. + """ + if len(self.layers) == 0 or not (hasattr(self.layers[0], "features")): + return [] + else: + return self.layers[0].features.keys() diff --git a/src/napari_matplotlib/scatter.py b/src/napari_matplotlib/scatter.py index 4f69fa78..f29c2ef6 100644 --- a/src/napari_matplotlib/scatter.py +++ b/src/napari_matplotlib/scatter.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Optional, Tuple, Union +from typing import Any, Dict, Optional, Tuple, Union import napari import numpy.typing as npt @@ -141,21 +141,6 @@ def y_axis_key(self, key: str) -> None: self._selectors["y"].setCurrentText(key) self._draw() - def _get_valid_axis_keys(self) -> List[str]: - """ - Get the valid axis keys from the layer FeatureTable. - - Returns - ------- - axis_keys : List[str] - The valid axis keys in the FeatureTable. If the table is empty - or there isn't a table, returns an empty list. - """ - if len(self.layers) == 0 or not (hasattr(self.layers[0], "features")): - return [] - else: - return self.layers[0].features.keys() - def _ready_to_scatter(self) -> bool: """ Return True if selected layer has a feature table we can scatter with, From 7c51b5a344d25ed9c7a674747c3f62a1e5b9e861 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Tue, 13 Jun 2023 13:23:09 +0100 Subject: [PATCH 03/12] Move layout setup --- src/napari_matplotlib/features.py | 23 ++++++++++++++++++++++- src/napari_matplotlib/scatter.py | 19 ++++--------------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/napari_matplotlib/features.py b/src/napari_matplotlib/features.py index f55592c2..e11e68ca 100644 --- a/src/napari_matplotlib/features.py +++ b/src/napari_matplotlib/features.py @@ -1,6 +1,8 @@ -from typing import List +from typing import Dict, List +import napari import napari.layers +from qtpy.QtWidgets import QComboBox, QLabel, QVBoxLayout from napari_matplotlib.base import NapariMPLWidget from napari_matplotlib.util import Interval @@ -10,6 +12,12 @@ class FeaturesMixin(NapariMPLWidget): """ Mixin to help with widgets that plot data from a features table stored on a single layer. + + Notes + ----- + This currently only works for widgets that plot two quatities against each other + e.g., scatter plots. It is intended to be generalised in the future for widgets + that plot one quantity e.g., histograms. """ n_layers_input = Interval(1, 1) @@ -22,6 +30,19 @@ class FeaturesMixin(NapariMPLWidget): napari.layers.Vectors, ) + def __init__(self) -> None: + # Set up selection boxes + self.layout().addLayout(QVBoxLayout()) + + self._selectors: Dict[str, QComboBox] = {} + for dim in ["x", "y"]: + self._selectors[dim] = QComboBox() + # Re-draw when combo boxes are updated + self._selectors[dim].currentTextChanged.connect(self._draw) + + self.layout().addWidget(QLabel(f"{dim}-axis:")) + self.layout().addWidget(self._selectors[dim]) + def _get_valid_axis_keys(self) -> List[str]: """ Get the valid axis keys from the layer FeatureTable. diff --git a/src/napari_matplotlib/scatter.py b/src/napari_matplotlib/scatter.py index f29c2ef6..892dd72a 100644 --- a/src/napari_matplotlib/scatter.py +++ b/src/napari_matplotlib/scatter.py @@ -1,8 +1,8 @@ -from typing import Any, Dict, Optional, Tuple, Union +from typing import Any, Optional, Tuple, Union import napari import numpy.typing as npt -from qtpy.QtWidgets import QComboBox, QLabel, QVBoxLayout, QWidget +from qtpy.QtWidgets import QWidget from .base import SingleAxesWidget from .features import FeaturesMixin @@ -96,19 +96,8 @@ def __init__( napari_viewer: napari.viewer.Viewer, parent: Optional[QWidget] = None, ): - super().__init__(napari_viewer, parent=parent) - - self.layout().addLayout(QVBoxLayout()) - - self._selectors: Dict[str, QComboBox] = {} - for dim in ["x", "y"]: - self._selectors[dim] = QComboBox() - # Re-draw when combo boxes are updated - self._selectors[dim].currentTextChanged.connect(self._draw) - - self.layout().addWidget(QLabel(f"{dim}-axis:")) - self.layout().addWidget(self._selectors[dim]) - + ScatterBaseWidget.__init__(self, napari_viewer, parent=parent) + FeaturesMixin.__init__(self) self._update_layers(None) @property From 75e79b6610be3f5d46eba54130e61f006bf9bf2f Mon Sep 17 00:00:00 2001 From: David Stansby Date: Tue, 13 Jun 2023 13:36:33 +0100 Subject: [PATCH 04/12] Move key setting/getting --- src/napari_matplotlib/features.py | 30 ++++++++---- src/napari_matplotlib/scatter.py | 46 ++++--------------- .../tests/scatter/test_scatter_features.py | 8 ++-- 3 files changed, 33 insertions(+), 51 deletions(-) diff --git a/src/napari_matplotlib/features.py b/src/napari_matplotlib/features.py index e11e68ca..bd40f1a3 100644 --- a/src/napari_matplotlib/features.py +++ b/src/napari_matplotlib/features.py @@ -1,4 +1,4 @@ -from typing import Dict, List +from typing import Dict, List, Optional import napari import napari.layers @@ -12,12 +12,6 @@ class FeaturesMixin(NapariMPLWidget): """ Mixin to help with widgets that plot data from a features table stored on a single layer. - - Notes - ----- - This currently only works for widgets that plot two quatities against each other - e.g., scatter plots. It is intended to be generalised in the future for widgets - that plot one quantity e.g., histograms. """ n_layers_input = Interval(1, 1) @@ -30,12 +24,14 @@ class FeaturesMixin(NapariMPLWidget): napari.layers.Vectors, ) - def __init__(self) -> None: + def __init__(self, *, ndim: int) -> None: + assert ndim in [1, 2] + self.dims = ["x", "y"][:ndim] # Set up selection boxes self.layout().addLayout(QVBoxLayout()) self._selectors: Dict[str, QComboBox] = {} - for dim in ["x", "y"]: + for dim in self.dims: self._selectors[dim] = QComboBox() # Re-draw when combo boxes are updated self._selectors[dim].currentTextChanged.connect(self._draw) @@ -43,6 +39,22 @@ def __init__(self) -> None: self.layout().addWidget(QLabel(f"{dim}-axis:")) self.layout().addWidget(self._selectors[dim]) + def get_key(self, dim: str) -> Optional[str]: + """ + Get key for a given dimension. + """ + if self._selectors[dim].count() == 0: + return None + else: + return self._selectors[dim].currentText() + + def set_key(self, dim: str, value: str) -> None: + """ + Set key for a given dimension. + """ + self._selectors[dim].setCurrentText(value) + self._draw() + def _get_valid_axis_keys(self) -> List[str]: """ Get the valid axis keys from the layer FeatureTable. diff --git a/src/napari_matplotlib/scatter.py b/src/napari_matplotlib/scatter.py index 892dd72a..27904d94 100644 --- a/src/napari_matplotlib/scatter.py +++ b/src/napari_matplotlib/scatter.py @@ -1,4 +1,4 @@ -from typing import Any, Optional, Tuple, Union +from typing import Any, Optional, Tuple import napari import numpy.typing as npt @@ -97,39 +97,9 @@ def __init__( parent: Optional[QWidget] = None, ): ScatterBaseWidget.__init__(self, napari_viewer, parent=parent) - FeaturesMixin.__init__(self) + FeaturesMixin.__init__(self, ndim=2) self._update_layers(None) - @property - def x_axis_key(self) -> Union[str, None]: - """ - Key for the x-axis data. - """ - if self._selectors["x"].count() == 0: - return None - else: - return self._selectors["x"].currentText() - - @x_axis_key.setter - def x_axis_key(self, key: str) -> None: - self._selectors["x"].setCurrentText(key) - self._draw() - - @property - def y_axis_key(self) -> Union[str, None]: - """ - Key for the y-axis data. - """ - if self._selectors["y"].count() == 0: - return None - else: - return self._selectors["y"].currentText() - - @y_axis_key.setter - def y_axis_key(self, key: str) -> None: - self._selectors["y"].setCurrentText(key) - self._draw() - def _ready_to_scatter(self) -> bool: """ Return True if selected layer has a feature table we can scatter with, @@ -143,8 +113,8 @@ def _ready_to_scatter(self) -> bool: return ( feature_table is not None and len(feature_table) > 0 - and self.x_axis_key in valid_keys - and self.y_axis_key in valid_keys + and self.get_key("x") in valid_keys + and self.get_key("y") in valid_keys ) def draw(self) -> None: @@ -173,11 +143,11 @@ def _get_data(self) -> Tuple[npt.NDArray[Any], npt.NDArray[Any], str, str]: """ feature_table = self.layers[0].features - x = feature_table[self.x_axis_key] - y = feature_table[self.y_axis_key] + x = feature_table[self.get_key("x")] + y = feature_table[self.get_key("y")] - x_axis_name = str(self.x_axis_key) - y_axis_name = str(self.y_axis_key) + x_axis_name = str(self.get_key("x")) + y_axis_name = str(self.get_key("y")) return x, y, x_axis_name, y_axis_name diff --git a/src/napari_matplotlib/tests/scatter/test_scatter_features.py b/src/napari_matplotlib/tests/scatter/test_scatter_features.py index c211a064..0b3f7638 100644 --- a/src/napari_matplotlib/tests/scatter/test_scatter_features.py +++ b/src/napari_matplotlib/tests/scatter/test_scatter_features.py @@ -25,8 +25,8 @@ def test_features_scatter_widget_2D( # Select points data and chosen features viewer.layers.selection.add(viewer.layers[0]) # images need to be selected - widget.x_axis_key = "feature_0" - widget.y_axis_key = "feature_1" + widget.set_key("x", "feature_0") + widget.set_key("y", "feature_1") fig = widget.figure @@ -64,9 +64,9 @@ def test_features_scatter_get_data(make_napari_viewer): viewer.layers.selection = [labels_layer] x_column = "feature_0" - scatter_widget.x_axis_key = x_column y_column = "feature_2" - scatter_widget.y_axis_key = y_column + scatter_widget.set_key("x", x_column) + scatter_widget.set_key("y", y_column) x, y, x_axis_name, y_axis_name = scatter_widget._get_data() np.testing.assert_allclose(x, feature_table[x_column]) From b56c56c98adae0bf0136961615a1ea5496fa59b6 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Tue, 13 Jun 2023 13:39:06 +0100 Subject: [PATCH 05/12] Move on_update_layers --- src/napari_matplotlib/features.py | 11 +++++++++++ src/napari_matplotlib/scatter.py | 11 ----------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/napari_matplotlib/features.py b/src/napari_matplotlib/features.py index bd40f1a3..58252ef2 100644 --- a/src/napari_matplotlib/features.py +++ b/src/napari_matplotlib/features.py @@ -69,3 +69,14 @@ def _get_valid_axis_keys(self) -> List[str]: return [] else: return self.layers[0].features.keys() + + def on_update_layers(self) -> None: + """ + Called when the layer selection changes by ``self.update_layers()``. + """ + # Clear combobox + for dim in self.dims: + while self._selectors[dim].count() > 0: + self._selectors[dim].removeItem(0) + # Add keys for newly selected layer + self._selectors[dim].addItems(self._get_valid_axis_keys()) diff --git a/src/napari_matplotlib/scatter.py b/src/napari_matplotlib/scatter.py index 27904d94..ed9e2efb 100644 --- a/src/napari_matplotlib/scatter.py +++ b/src/napari_matplotlib/scatter.py @@ -150,14 +150,3 @@ def _get_data(self) -> Tuple[npt.NDArray[Any], npt.NDArray[Any], str, str]: y_axis_name = str(self.get_key("y")) return x, y, x_axis_name, y_axis_name - - def on_update_layers(self) -> None: - """ - Called when the layer selection changes by ``self.update_layers()``. - """ - # Clear combobox - for dim in ["x", "y"]: - while self._selectors[dim].count() > 0: - self._selectors[dim].removeItem(0) - # Add keys for newly selected layer - self._selectors[dim].addItems(self._get_valid_axis_keys()) From ddf81ff1b0787428787f87a551b8323e7d0b021b Mon Sep 17 00:00:00 2001 From: David Stansby Date: Tue, 13 Jun 2023 13:43:31 +0100 Subject: [PATCH 06/12] Move ready_to_plot --- src/napari_matplotlib/features.py | 16 ++++++++++++++++ src/napari_matplotlib/scatter.py | 19 +------------------ 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/napari_matplotlib/features.py b/src/napari_matplotlib/features.py index 58252ef2..4b1c67b4 100644 --- a/src/napari_matplotlib/features.py +++ b/src/napari_matplotlib/features.py @@ -70,6 +70,22 @@ def _get_valid_axis_keys(self) -> List[str]: else: return self.layers[0].features.keys() + def _ready_to_plot(self) -> bool: + """ + Return True if selected layer has a feature table we can plot with, + and the columns to plot have been selected. + """ + if not hasattr(self.layers[0], "features"): + return False + + feature_table = self.layers[0].features + valid_keys = self._get_valid_axis_keys() + return ( + feature_table is not None + and len(feature_table) > 0 + and all([self.get_key(dim) in valid_keys for dim in self.dims]) + ) + def on_update_layers(self) -> None: """ Called when the layer selection changes by ``self.update_layers()``. diff --git a/src/napari_matplotlib/scatter.py b/src/napari_matplotlib/scatter.py index ed9e2efb..95721161 100644 --- a/src/napari_matplotlib/scatter.py +++ b/src/napari_matplotlib/scatter.py @@ -100,28 +100,11 @@ def __init__( FeaturesMixin.__init__(self, ndim=2) self._update_layers(None) - def _ready_to_scatter(self) -> bool: - """ - Return True if selected layer has a feature table we can scatter with, - and the two columns to be scatterd have been selected. - """ - if not hasattr(self.layers[0], "features"): - return False - - feature_table = self.layers[0].features - valid_keys = self._get_valid_axis_keys() - return ( - feature_table is not None - and len(feature_table) > 0 - and self.get_key("x") in valid_keys - and self.get_key("y") in valid_keys - ) - def draw(self) -> None: """ Scatter two features from the currently selected layer. """ - if self._ready_to_scatter(): + if self._ready_to_plot(): super().draw() def _get_data(self) -> Tuple[npt.NDArray[Any], npt.NDArray[Any], str, str]: From 91368c1802681d9e402b3b305fe8f7f3cdf8045d Mon Sep 17 00:00:00 2001 From: David Stansby Date: Tue, 13 Jun 2023 13:56:49 +0100 Subject: [PATCH 07/12] Move data getting --- src/napari_matplotlib/features.py | 26 +++++++++++++++++++++++++- src/napari_matplotlib/scatter.py | 27 ++------------------------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/napari_matplotlib/features.py b/src/napari_matplotlib/features.py index 4b1c67b4..2845c21e 100644 --- a/src/napari_matplotlib/features.py +++ b/src/napari_matplotlib/features.py @@ -1,7 +1,10 @@ -from typing import Dict, List, Optional +from typing import Any, Dict, List, Optional, Tuple import napari import napari.layers +import numpy as np +import numpy.typing as npt +import pandas as pd from qtpy.QtWidgets import QComboBox, QLabel, QVBoxLayout from napari_matplotlib.base import NapariMPLWidget @@ -86,6 +89,27 @@ def _ready_to_plot(self) -> bool: and all([self.get_key(dim) in valid_keys for dim in self.dims]) ) + def _get_data_names( + self, + ) -> Tuple[List[npt.NDArray[Any]], List[str]]: + """ + Get the plot data from the ``features`` attribute of the first + selected layer. + + Returns + ------- + data : List[np.ndarray] + List contains X and Y columns from the FeatureTable. Returns + an empty array if nothing to plot. + names : List[str] + Names for each axis. + """ + feature_table: pd.DataFrame = self.layers[0].features + + names = [str(self.get_key(dim)) for dim in self.dims] + data = [np.array(feature_table[key]) for key in names] + return data, names + def on_update_layers(self) -> None: """ Called when the layer selection changes by ``self.update_layers()``. diff --git a/src/napari_matplotlib/scatter.py b/src/napari_matplotlib/scatter.py index 95721161..4fa45798 100644 --- a/src/napari_matplotlib/scatter.py +++ b/src/napari_matplotlib/scatter.py @@ -108,28 +108,5 @@ def draw(self) -> None: super().draw() def _get_data(self) -> Tuple[npt.NDArray[Any], npt.NDArray[Any], str, str]: - """ - Get the plot data from the ``features`` attribute of the first - selected layer. - - Returns - ------- - data : List[np.ndarray] - List contains X and Y columns from the FeatureTable. Returns - an empty array if nothing to plot. - x_axis_name : str - The title to display on the x axis. Returns - an empty string if nothing to plot. - y_axis_name: str - The title to display on the y axis. Returns - an empty string if nothing to plot. - """ - feature_table = self.layers[0].features - - x = feature_table[self.get_key("x")] - y = feature_table[self.get_key("y")] - - x_axis_name = str(self.get_key("x")) - y_axis_name = str(self.get_key("y")) - - return x, y, x_axis_name, y_axis_name + data, names = self._get_data_names() + return data[0], data[1], names[0], names[1] From e1870d6d59ee9560befd57bfff52cf7c39f9bf02 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Thu, 15 Jun 2023 13:58:29 +0100 Subject: [PATCH 08/12] Fix super() --- src/napari_matplotlib/base.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/napari_matplotlib/base.py b/src/napari_matplotlib/base.py index 8c717d6a..5687895e 100644 --- a/src/napari_matplotlib/base.py +++ b/src/napari_matplotlib/base.py @@ -281,7 +281,9 @@ def __init__( napari_viewer: napari.viewer.Viewer, parent: Optional[QWidget] = None, ): - super().__init__(napari_viewer=napari_viewer, parent=parent) + NapariMPLWidget.__init__( + self, napari_viewer=napari_viewer, parent=parent + ) self.add_single_axes() def clear(self) -> None: From a04bd18b169f696d95ecaad2bbb6d3059995f5de Mon Sep 17 00:00:00 2001 From: David Stansby Date: Thu, 15 Jun 2023 14:03:01 +0100 Subject: [PATCH 09/12] Add features to API doc --- docs/api.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/api.rst b/docs/api.rst index dba583af..ae0d78d2 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -8,3 +8,5 @@ plots though the napari user interface. .. automodapi:: napari_matplotlib .. automodapi:: napari_matplotlib.base + +.. automodapi:: napari_matplotlib.features From c0909d3b43e6b6808e92aa1de0aa6335286551d6 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Thu, 15 Jun 2023 14:09:20 +0100 Subject: [PATCH 10/12] Add __all__ --- src/napari_matplotlib/features.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/napari_matplotlib/features.py b/src/napari_matplotlib/features.py index 2845c21e..c1991819 100644 --- a/src/napari_matplotlib/features.py +++ b/src/napari_matplotlib/features.py @@ -10,6 +10,7 @@ from napari_matplotlib.base import NapariMPLWidget from napari_matplotlib.util import Interval +__all__ = ["FeaturesMixin"] class FeaturesMixin(NapariMPLWidget): """ From 5e5afd18c324e563662c0079ded1bd77ee0c46bf Mon Sep 17 00:00:00 2001 From: David Stansby Date: Thu, 15 Jun 2023 14:45:35 +0100 Subject: [PATCH 11/12] Improve FeaturesMixin docs --- src/napari_matplotlib/features.py | 33 +++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/napari_matplotlib/features.py b/src/napari_matplotlib/features.py index c1991819..899687b4 100644 --- a/src/napari_matplotlib/features.py +++ b/src/napari_matplotlib/features.py @@ -12,10 +12,16 @@ __all__ = ["FeaturesMixin"] + class FeaturesMixin(NapariMPLWidget): """ Mixin to help with widgets that plot data from a features table stored - on a single layer. + in a single napari layer. + + This provides: + - Setup for one or two combo boxes to select features to be plotted. + - An ``on_update_layers()`` callback that updates the combo box options + when the napari layer selection changes. """ n_layers_input = Interval(1, 1) @@ -29,6 +35,13 @@ class FeaturesMixin(NapariMPLWidget): ) def __init__(self, *, ndim: int) -> None: + """ + Parameters + ---------- + ndim : int + Number of dimensions that are plotted by the widget. + Must be 1 or 2. + """ assert ndim in [1, 2] self.dims = ["x", "y"][:ndim] # Set up selection boxes @@ -46,6 +59,11 @@ def __init__(self, *, ndim: int) -> None: def get_key(self, dim: str) -> Optional[str]: """ Get key for a given dimension. + + Parameters + ---------- + dim : str + "x" or "y" """ if self._selectors[dim].count() == 0: return None @@ -55,13 +73,24 @@ def get_key(self, dim: str) -> Optional[str]: def set_key(self, dim: str, value: str) -> None: """ Set key for a given dimension. + + Parameters + ---------- + dim : str + "x" or "y" + value : str + Value to set. """ + assert value in self._get_valid_axis_keys(), ( + "value must be on of the columns " + "of the feature table on the currently seleted layer" + ) self._selectors[dim].setCurrentText(value) self._draw() def _get_valid_axis_keys(self) -> List[str]: """ - Get the valid axis keys from the layer FeatureTable. + Get the valid axis keys from the features table column names. Returns ------- From 8c2df620cf2038b7ae81f87bd3ac837a5902ee84 Mon Sep 17 00:00:00 2001 From: David Stansby Date: Thu, 15 Jun 2023 14:56:49 +0100 Subject: [PATCH 12/12] Fix bullet points --- src/napari_matplotlib/features.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/napari_matplotlib/features.py b/src/napari_matplotlib/features.py index 899687b4..3e1eb9ba 100644 --- a/src/napari_matplotlib/features.py +++ b/src/napari_matplotlib/features.py @@ -19,6 +19,7 @@ class FeaturesMixin(NapariMPLWidget): in a single napari layer. This provides: + - Setup for one or two combo boxes to select features to be plotted. - An ``on_update_layers()`` callback that updates the combo box options when the napari layer selection changes. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy