Skip to content

Commit d7e88a9

Browse files
authored
Merge pull request #205 from dstansby/slice-test-ndim
Fix slicing 2D images
2 parents cee4975 + 08ee5d0 commit d7e88a9

File tree

5 files changed

+45
-13
lines changed

5 files changed

+45
-13
lines changed

Diff for: docs/changelog.rst

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
Changelog
22
=========
3+
1.0.3
4+
-----
5+
Bug fixes
6+
~~~~~~~~~
7+
- Fixed creating 1D slices of 2D images.
8+
39
1.0.2
410
-----
511
Bug fixes

Diff for: src/napari_matplotlib/slice.py

+27-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Dict, Optional, Tuple
1+
from typing import Any, Dict, List, Optional, Tuple
22

33
import matplotlib.ticker as mticker
44
import napari
@@ -12,7 +12,6 @@
1212
__all__ = ["SliceWidget"]
1313

1414
_dims_sel = ["x", "y"]
15-
_dims = ["x", "y", "z"]
1615

1716

1817
class SliceWidget(SingleAxesWidget):
@@ -37,7 +36,7 @@ def __init__(
3736
self.dim_selector = QComboBox()
3837
button_layout.addWidget(QLabel("Slice axis:"))
3938
button_layout.addWidget(self.dim_selector)
40-
self.dim_selector.addItems(_dims)
39+
self.dim_selector.addItems(["x", "y", "z"])
4140

4241
self.slice_selectors = {}
4342
for d in _dims_sel:
@@ -61,7 +60,7 @@ def _layer(self) -> napari.layers.Layer:
6160
return self.layers[0]
6261

6362
@property
64-
def current_dim(self) -> str:
63+
def current_dim_name(self) -> str:
6564
"""
6665
Currently selected slice dimension.
6766
"""
@@ -74,32 +73,50 @@ def current_dim_index(self) -> int:
7473
"""
7574
# Note the reversed list because in napari the z-axis is the first
7675
# 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")
7890

7991
@property
8092
def _selector_values(self) -> Dict[str, int]:
8193
"""
8294
Values of the slice selectors.
95+
96+
Mapping from dimension name to value.
8397
"""
8498
return {d: self.slice_selectors[d].value() for d in _dims_sel}
8599

86100
def _get_xy(self) -> Tuple[npt.NDArray[Any], npt.NDArray[Any]]:
87101
"""
88102
Get data for plotting.
89103
"""
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])
91108

92109
vals = self._selector_values
93110
vals.update({"z": self.current_z})
94111

95112
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:
98115
# Select all data along this axis
99116
slices.append(slice(None))
100117
else:
101118
# Select specific index
102-
val = vals[d]
119+
val = vals[dim_name]
103120
slices.append(slice(val, val + 1))
104121

105122
# Reverse since z is the first axis in napari
@@ -115,7 +132,7 @@ def draw(self) -> None:
115132
x, y = self._get_xy()
116133

117134
self.axes.plot(x, y)
118-
self.axes.set_xlabel(self.current_dim)
135+
self.axes.set_xlabel(self.current_dim_name)
119136
self.axes.set_title(self._layer.name)
120137
# Make sure all ticks lie on integer values
121138
self.axes.xaxis.set_major_locator(
12.2 KB
Loading
-342 Bytes
Loading

Diff for: src/napari_matplotlib/tests/test_slice.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@
99
def test_slice_3D(make_napari_viewer, brain_data):
1010
viewer = make_napari_viewer()
1111
viewer.theme = "light"
12-
viewer.add_image(brain_data[0], **brain_data[1])
12+
13+
data = brain_data[0]
14+
assert data.ndim == 3, data.shape
15+
viewer.add_image(data, **brain_data[1])
16+
1317
axis = viewer.dims.last_used
14-
slice_no = brain_data[0].shape[0] - 1
18+
slice_no = data.shape[0] - 1
1519
viewer.dims.set_current_step(axis, slice_no)
1620
fig = SliceWidget(viewer).figure
1721
# Need to return a copy, as original figure is too eagerley garbage
@@ -23,7 +27,12 @@ def test_slice_3D(make_napari_viewer, brain_data):
2327
def test_slice_2D(make_napari_viewer, astronaut_data):
2428
viewer = make_napari_viewer()
2529
viewer.theme = "light"
26-
viewer.add_image(astronaut_data[0], **astronaut_data[1])
30+
31+
# Take first RGB channel
32+
data = astronaut_data[0][:, :, 0]
33+
assert data.ndim == 2, data.shape
34+
viewer.add_image(data)
35+
2736
fig = SliceWidget(viewer).figure
2837
# Need to return a copy, as original figure is too eagerley garbage
2938
# collected by the widget

0 commit comments

Comments
 (0)