1
- from typing import Any , Dict , Optional , Tuple
1
+ from typing import Any , Dict , List , Optional , Tuple
2
2
3
3
import matplotlib .ticker as mticker
4
4
import napari
12
12
__all__ = ["SliceWidget" ]
13
13
14
14
_dims_sel = ["x" , "y" ]
15
- _dims = ["x" , "y" , "z" ]
16
15
17
16
18
17
class SliceWidget (SingleAxesWidget ):
@@ -37,7 +36,7 @@ def __init__(
37
36
self .dim_selector = QComboBox ()
38
37
button_layout .addWidget (QLabel ("Slice axis:" ))
39
38
button_layout .addWidget (self .dim_selector )
40
- self .dim_selector .addItems (_dims )
39
+ self .dim_selector .addItems ([ "x" , "y" , "z" ] )
41
40
42
41
self .slice_selectors = {}
43
42
for d in _dims_sel :
@@ -61,7 +60,7 @@ def _layer(self) -> napari.layers.Layer:
61
60
return self .layers [0 ]
62
61
63
62
@property
64
- def current_dim (self ) -> str :
63
+ def current_dim_name (self ) -> str :
65
64
"""
66
65
Currently selected slice dimension.
67
66
"""
@@ -74,32 +73,50 @@ def current_dim_index(self) -> int:
74
73
"""
75
74
# Note the reversed list because in napari the z-axis is the first
76
75
# numpy axis
77
- return _dims [::- 1 ].index (self .current_dim )
76
+ return self ._dim_names [::- 1 ].index (self .current_dim_name )
77
+
78
+ @property
79
+ def _dim_names (self ) -> List [str ]:
80
+ """
81
+ List of dimension names. This is a property as it varies depending on the
82
+ dimensionality of the currently selected data.
83
+ """
84
+ if self ._layer .data .ndim == 2 :
85
+ return ["x" , "y" ]
86
+ elif self ._layer .data .ndim == 3 :
87
+ return ["x" , "y" , "z" ]
88
+ else :
89
+ raise RuntimeError ("Don't know how to handle ndim != 2 or 3" )
78
90
79
91
@property
80
92
def _selector_values (self ) -> Dict [str , int ]:
81
93
"""
82
94
Values of the slice selectors.
95
+
96
+ Mapping from dimension name to value.
83
97
"""
84
98
return {d : self .slice_selectors [d ].value () for d in _dims_sel }
85
99
86
100
def _get_xy (self ) -> Tuple [npt .NDArray [Any ], npt .NDArray [Any ]]:
87
101
"""
88
102
Get data for plotting.
89
103
"""
90
- x = np .arange (self ._layer .data .shape [self .current_dim_index ])
104
+ dim_index = self .current_dim_index
105
+ if self ._layer .data .ndim == 2 :
106
+ dim_index -= 1
107
+ x = np .arange (self ._layer .data .shape [dim_index ])
91
108
92
109
vals = self ._selector_values
93
110
vals .update ({"z" : self .current_z })
94
111
95
112
slices = []
96
- for d in _dims :
97
- if d == self .current_dim :
113
+ for dim_name in self . _dim_names :
114
+ if dim_name == self .current_dim_name :
98
115
# Select all data along this axis
99
116
slices .append (slice (None ))
100
117
else :
101
118
# Select specific index
102
- val = vals [d ]
119
+ val = vals [dim_name ]
103
120
slices .append (slice (val , val + 1 ))
104
121
105
122
# Reverse since z is the first axis in napari
@@ -115,7 +132,7 @@ def draw(self) -> None:
115
132
x , y = self ._get_xy ()
116
133
117
134
self .axes .plot (x , y )
118
- self .axes .set_xlabel (self .current_dim )
135
+ self .axes .set_xlabel (self .current_dim_name )
119
136
self .axes .set_title (self ._layer .name )
120
137
# Make sure all ticks lie on integer values
121
138
self .axes .xaxis .set_major_locator (
0 commit comments