1
- from typing import Any , List , Optional , Tuple
1
+ from typing import Any , Dict , List , Optional , Tuple , Union
2
2
3
3
import napari
4
4
import numpy .typing as npt
5
- from magicgui import magicgui
6
- from magicgui .widgets import ComboBox
5
+ from qtpy .QtWidgets import QComboBox , QLabel , QVBoxLayout , QWidget
7
6
8
7
from .base import NapariMPLWidget
9
8
from .util import Interval
@@ -20,11 +19,13 @@ class ScatterBaseWidget(NapariMPLWidget):
20
19
# the scatter is plotted as a 2D histogram
21
20
_threshold_to_switch_to_histogram = 500
22
21
23
- def __init__ (self , napari_viewer : napari .viewer .Viewer ):
24
- super ().__init__ (napari_viewer )
25
-
22
+ def __init__ (
23
+ self ,
24
+ napari_viewer : napari .viewer .Viewer ,
25
+ parent : Optional [QWidget ] = None ,
26
+ ):
27
+ super ().__init__ (napari_viewer , parent = parent )
26
28
self .add_single_axes ()
27
- self .update_layers (None )
28
29
29
30
def clear (self ) -> None :
30
31
"""
@@ -113,55 +114,57 @@ class FeaturesScatterWidget(ScatterBaseWidget):
113
114
napari .layers .Vectors ,
114
115
)
115
116
116
- def __init__ (self , napari_viewer : napari . viewer . Viewer ):
117
- super (). __init__ ( napari_viewer )
118
- self . _key_selection_widget = magicgui (
119
- self . _set_axis_keys ,
120
- x_axis_key = { "choices" : self . _get_valid_axis_keys },
121
- y_axis_key = { "choices" : self . _get_valid_axis_keys },
122
- call_button = "plot" ,
123
- )
117
+ def __init__ (
118
+ self ,
119
+ napari_viewer : napari . viewer . Viewer ,
120
+ parent : Optional [ QWidget ] = None ,
121
+ ):
122
+ super (). __init__ ( napari_viewer , parent = parent )
123
+
124
+ self . layout (). addLayout ( QVBoxLayout () )
124
125
125
- self .layout ().addWidget (self ._key_selection_widget .native )
126
+ self ._selectors : Dict [str , QComboBox ] = {}
127
+ for dim in ["x" , "y" ]:
128
+ self ._selectors [dim ] = QComboBox ()
129
+ # Re-draw when combo boxes are updated
130
+ self ._selectors [dim ].currentTextChanged .connect (self ._draw )
131
+
132
+ self .layout ().addWidget (QLabel (f"{ dim } -axis:" ))
133
+ self .layout ().addWidget (self ._selectors [dim ])
134
+
135
+ self .update_layers (None )
126
136
127
137
@property
128
- def x_axis_key (self ) -> Optional [str ]:
138
+ def x_axis_key (self ) -> Union [str , None ]:
129
139
"""
130
140
Key to access x axis data from the FeaturesTable.
131
141
"""
132
- return self ._x_axis_key
142
+ if self ._selectors ["x" ].count () == 0 :
143
+ return None
144
+ else :
145
+ return self ._selectors ["x" ].currentText ()
133
146
134
147
@x_axis_key .setter
135
- def x_axis_key (self , key : Optional [ str ] ) -> None :
136
- self ._x_axis_key = key
148
+ def x_axis_key (self , key : str ) -> None :
149
+ self ._selectors [ "x" ]. setCurrentText ( key )
137
150
self ._draw ()
138
151
139
152
@property
140
- def y_axis_key (self ) -> Optional [str ]:
153
+ def y_axis_key (self ) -> Union [str , None ]:
141
154
"""
142
155
Key to access y axis data from the FeaturesTable.
143
156
"""
144
- return self ._y_axis_key
157
+ if self ._selectors ["y" ].count () == 0 :
158
+ return None
159
+ else :
160
+ return self ._selectors ["y" ].currentText ()
145
161
146
162
@y_axis_key .setter
147
- def y_axis_key (self , key : Optional [str ]) -> None :
148
- """
149
- Set the y-axis key.
150
- """
151
- self ._y_axis_key = key
152
- self ._draw ()
153
-
154
- def _set_axis_keys (self , x_axis_key : str , y_axis_key : str ) -> None :
155
- """
156
- Set both axis keys and then redraw the plot.
157
- """
158
- self ._x_axis_key = x_axis_key
159
- self ._y_axis_key = y_axis_key
163
+ def y_axis_key (self , key : str ) -> None :
164
+ self ._selectors ["y" ].setCurrentText (key )
160
165
self ._draw ()
161
166
162
- def _get_valid_axis_keys (
163
- self , combo_widget : Optional [ComboBox ] = None
164
- ) -> List [str ]:
167
+ def _get_valid_axis_keys (self ) -> List [str ]:
165
168
"""
166
169
Get the valid axis keys from the layer FeatureTable.
167
170
@@ -185,11 +188,12 @@ def _ready_to_scatter(self) -> bool:
185
188
return False
186
189
187
190
feature_table = self .layers [0 ].features
191
+ valid_keys = self ._get_valid_axis_keys ()
188
192
return (
189
193
feature_table is not None
190
194
and len (feature_table ) > 0
191
- and self .x_axis_key is not None
192
- and self .y_axis_key is not None
195
+ and self .x_axis_key in valid_keys
196
+ and self .y_axis_key in valid_keys
193
197
)
194
198
195
199
def draw (self ) -> None :
@@ -230,9 +234,9 @@ def _on_update_layers(self) -> None:
230
234
"""
231
235
Called when the layer selection changes by ``self.update_layers()``.
232
236
"""
233
- if hasattr ( self , "_key_selection_widget" ):
234
- self . _key_selection_widget . reset_choices ()
235
-
236
- # reset the axis keys
237
- self . _x_axis_key = None
238
- self . _y_axis_key = None
237
+ # Clear combobox
238
+ for dim in [ "x" , "y" ]:
239
+ while self . _selectors [ dim ]. count () > 0 :
240
+ self . _selectors [ dim ]. removeItem ( 0 )
241
+ # Add keys for newly selected layer
242
+ self . _selectors [ dim ]. addItems ( self . _get_valid_axis_keys ())
0 commit comments