Skip to content

Commit f697618

Browse files
committed
moved new widget to histogram.py
1 parent 4dcb43e commit f697618

File tree

2 files changed

+124
-123
lines changed

2 files changed

+124
-123
lines changed

src/napari_matplotlib/histogram.py

Lines changed: 124 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
from typing import Optional
1+
from typing import Optional, List, Tuple
22

33
import napari
44
import numpy as np
55
from qtpy.QtWidgets import QWidget
6+
from magicgui import magicgui, ComboBox
67

78
from .base import NapariMPLWidget
89
from .util import Interval
910

10-
__all__ = ["HistogramWidget"]
11+
__all__ = ["HistogramWidget", "FeaturesHistogramWidget"]
1112

1213
_COLORS = {"r": "tab:red", "g": "tab:green", "b": "tab:blue"}
1314

@@ -63,3 +64,124 @@ def draw(self) -> None:
6364
self.axes.hist(data.ravel(), bins=bins, label=layer.name)
6465

6566
self.axes.legend()
67+
68+
69+
class FeaturesHistogramWidget(NapariMPLWidget):
70+
n_layers_input = Interval(1, 1)
71+
# All layers that have a .features attributes
72+
input_layer_types = (
73+
napari.layers.Labels,
74+
napari.layers.Points,
75+
napari.layers.Shapes,
76+
napari.layers.Tracks,
77+
napari.layers.Vectors,
78+
)
79+
80+
def __init__(self, napari_viewer: napari.viewer.Viewer):
81+
super().__init__(napari_viewer)
82+
self.axes = self.canvas.figure.subplots()
83+
84+
self._key_selection_widget = magicgui(
85+
self._set_axis_keys,
86+
x_axis_key={"choices": self._get_valid_axis_keys},
87+
call_button="plot",
88+
)
89+
self.layout().addWidget(self._key_selection_widget.native)
90+
91+
self.update_layers(None)
92+
93+
def clear(self) -> None:
94+
"""
95+
Clear the axes.
96+
"""
97+
self.axes.clear()
98+
99+
self.layout().addWidget(self._key_selection_widget.native)
100+
101+
@property
102+
def x_axis_key(self) -> Optional[str]:
103+
"""Key to access x axis data from the FeaturesTable"""
104+
return self._x_axis_key
105+
106+
@x_axis_key.setter
107+
def x_axis_key(self, key: Optional[str]) -> None:
108+
self._x_axis_key = key
109+
self._draw()
110+
111+
def _set_axis_keys(self, x_axis_key: str) -> None:
112+
"""Set both axis keys and then redraw the plot"""
113+
self._x_axis_key = x_axis_key
114+
self._draw()
115+
116+
def _get_valid_axis_keys(
117+
self, combo_widget: Optional[ComboBox] = None
118+
) -> List[str]:
119+
"""
120+
Get the valid axis keys from the layer FeatureTable.
121+
122+
Returns
123+
-------
124+
axis_keys : List[str]
125+
The valid axis keys in the FeatureTable. If the table is empty
126+
or there isn't a table, returns an empty list.
127+
"""
128+
if len(self.layers) == 0 or not (hasattr(self.layers[0], "features")):
129+
return []
130+
else:
131+
return self.layers[0].features.keys()
132+
133+
def _get_data(self) -> Tuple[np.ndarray, str]:
134+
"""Get the plot data.
135+
136+
Returns
137+
-------
138+
data : List[np.ndarray]
139+
List contains X and Y columns from the FeatureTable. Returns
140+
an empty array if nothing to plot.
141+
x_axis_name : str
142+
The title to display on the x axis. Returns
143+
an empty string if nothing to plot.
144+
"""
145+
if not hasattr(self.layers[0], "features"):
146+
# if the selected layer doesn't have a featuretable,
147+
# skip draw
148+
return [], ""
149+
150+
feature_table = self.layers[0].features
151+
152+
if (
153+
(len(feature_table) == 0)
154+
or (self.x_axis_key is None)
155+
):
156+
return [], ""
157+
158+
data = feature_table[self.x_axis_key]
159+
x_axis_name = self.x_axis_key.replace("_", " ")
160+
161+
return data, x_axis_name
162+
163+
def _on_update_layers(self) -> None:
164+
"""
165+
This is called when the layer selection changes by
166+
``self.update_layers()``.
167+
"""
168+
if hasattr(self, "_key_selection_widget"):
169+
self._key_selection_widget.reset_choices()
170+
171+
# reset the axis keys
172+
self._x_axis_key = None
173+
174+
def draw(self) -> None:
175+
"""Clear the axes and histogram the currently selected layer/slice."""
176+
177+
data, x_axis_name = self._get_data()
178+
179+
if len(data) == 0:
180+
return
181+
182+
self.axes.hist(data, bins=50, edgecolor='white',
183+
linewidth=0.3)
184+
185+
# set ax labels
186+
self.axes.set_xlabel(x_axis_name)
187+
self.axes.set_ylabel('Counts [#]')

src/napari_matplotlib/scatter.py

Lines changed: 0 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -248,124 +248,3 @@ def on_update_layers(self) -> None:
248248
self._selectors[dim].removeItem(0)
249249
# Add keys for newly selected layer
250250
self._selectors[dim].addItems(self._get_valid_axis_keys())
251-
252-
253-
class FeaturesHistogramWidget(NapariMPLWidget):
254-
n_layers_input = Interval(1, 1)
255-
# All layers that have a .features attributes
256-
input_layer_types = (
257-
napari.layers.Labels,
258-
napari.layers.Points,
259-
napari.layers.Shapes,
260-
napari.layers.Tracks,
261-
napari.layers.Vectors,
262-
)
263-
264-
def __init__(self, napari_viewer: napari.viewer.Viewer):
265-
super().__init__(napari_viewer)
266-
self.axes = self.canvas.figure.subplots()
267-
268-
self._key_selection_widget = magicgui(
269-
self._set_axis_keys,
270-
x_axis_key={"choices": self._get_valid_axis_keys},
271-
call_button="plot",
272-
)
273-
self.layout().addWidget(self._key_selection_widget.native)
274-
275-
self.update_layers(None)
276-
277-
def clear(self) -> None:
278-
"""
279-
Clear the axes.
280-
"""
281-
self.axes.clear()
282-
283-
self.layout().addWidget(self._key_selection_widget.native)
284-
285-
@property
286-
def x_axis_key(self) -> Optional[str]:
287-
"""Key to access x axis data from the FeaturesTable"""
288-
return self._x_axis_key
289-
290-
@x_axis_key.setter
291-
def x_axis_key(self, key: Optional[str]) -> None:
292-
self._x_axis_key = key
293-
self._draw()
294-
295-
def _set_axis_keys(self, x_axis_key: str) -> None:
296-
"""Set both axis keys and then redraw the plot"""
297-
self._x_axis_key = x_axis_key
298-
self._draw()
299-
300-
def _get_valid_axis_keys(
301-
self, combo_widget: Optional[ComboBox] = None
302-
) -> List[str]:
303-
"""
304-
Get the valid axis keys from the layer FeatureTable.
305-
306-
Returns
307-
-------
308-
axis_keys : List[str]
309-
The valid axis keys in the FeatureTable. If the table is empty
310-
or there isn't a table, returns an empty list.
311-
"""
312-
if len(self.layers) == 0 or not (hasattr(self.layers[0], "features")):
313-
return []
314-
else:
315-
return self.layers[0].features.keys()
316-
317-
def _get_data(self) -> Tuple[np.ndarray, str]:
318-
"""Get the plot data.
319-
320-
Returns
321-
-------
322-
data : List[np.ndarray]
323-
List contains X and Y columns from the FeatureTable. Returns
324-
an empty array if nothing to plot.
325-
x_axis_name : str
326-
The title to display on the x axis. Returns
327-
an empty string if nothing to plot.
328-
"""
329-
if not hasattr(self.layers[0], "features"):
330-
# if the selected layer doesn't have a featuretable,
331-
# skip draw
332-
return [], ""
333-
334-
feature_table = self.layers[0].features
335-
336-
if (
337-
(len(feature_table) == 0)
338-
or (self.x_axis_key is None)
339-
):
340-
return [], ""
341-
342-
data = feature_table[self.x_axis_key]
343-
x_axis_name = self.x_axis_key.replace("_", " ")
344-
345-
return data, x_axis_name
346-
347-
def _on_update_layers(self) -> None:
348-
"""
349-
This is called when the layer selection changes by
350-
``self.update_layers()``.
351-
"""
352-
if hasattr(self, "_key_selection_widget"):
353-
self._key_selection_widget.reset_choices()
354-
355-
# reset the axis keys
356-
self._x_axis_key = None
357-
358-
def draw(self) -> None:
359-
"""Clear the axes and histogram the currently selected layer/slice."""
360-
361-
data, x_axis_name = self._get_data()
362-
363-
if len(data) == 0:
364-
return
365-
366-
self.axes.hist(data, bins=50, edgecolor='white',
367-
linewidth=0.3)
368-
369-
# set ax labels
370-
self.axes.set_xlabel(x_axis_name)
371-
self.axes.set_ylabel('Counts [#]')

0 commit comments

Comments
 (0)