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

docs/changelog.rst

Lines changed: 6 additions & 0 deletions
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

src/napari_matplotlib/slice.py

Lines changed: 27 additions & 10 deletions
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(
Loading
Loading

src/napari_matplotlib/tests/test_slice.py

Lines changed: 12 additions & 3 deletions
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)
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