Skip to content

Commit 760b841

Browse files
committed
Working slicer
1 parent 5b6feb6 commit 760b841

File tree

1 file changed

+66
-15
lines changed

1 file changed

+66
-15
lines changed

src/napari_matplotlib/slice.py

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,90 @@
1+
from typing import Dict
2+
13
import napari
4+
import numpy as np
25
from qtpy.QtWidgets import QComboBox, QHBoxLayout, QSpinBox
36

4-
from napari_matplotlib.base import NapariMPLWidget
7+
from napari_matplotlib.base import SingleLayerWidget
58

69
__all__ = ["SliceWidget"]
710

811
_dims = ["x", "y", "z"]
912

1013

1114
class SliceWidget(NapariMPLWidget):
15+
"""
16+
Plot a 1D slice along a given dimension.
17+
"""
18+
n_layers_input = 1
19+
1220
def __init__(self, napari_viewer: napari.viewer.Viewer):
1321
super().__init__(napari_viewer)
14-
15-
self.layer = self.viewer.layers[-1]
22+
self.axes = self.canvas.figure.subplots()
1623

1724
button_layout = QHBoxLayout()
1825
self.layout().addLayout(button_layout)
1926

2027
self.dim_selector = QComboBox()
2128
button_layout.addWidget(self.dim_selector)
29+
self.dim_selector.addItems(_dims)
2230

23-
self.selectors = {}
31+
self.slice_selectors = {}
2432
for d in _dims:
25-
self.selectors[d] = QSpinBox()
26-
button_layout.addWidget(self.selectors[d])
33+
self.slice_selectors[d] = QSpinBox()
34+
button_layout.addWidget(self.slice_selectors[d])
35+
36+
self.update_slice_selectors()
37+
self.draw()
38+
39+
@property
40+
def current_dim(self) -> str:
41+
"""
42+
Currently selected slice dimension.
43+
"""
44+
return self.dim_selector.currentText()
45+
46+
@property
47+
def current_dim_index(self) -> int:
48+
"""
49+
Currently selected slice dimension index.
50+
"""
51+
# Note the reversed list because in napari the z-axis is the first
52+
# numpy axis
53+
return _dims[::-1].index(self.current_dim)
2754

28-
self.update_dim_selector()
29-
self.viewer.layers.selection.events.changed.connect(
30-
self.update_dim_selector
31-
)
55+
@property
56+
def selector_values(self) -> Dict[str, int]:
57+
return {d: self.slice_selectors[d].value() for d in _dims}
3258

33-
def update_dim_selector(self) -> None:
59+
def update_slice_selectors(self) -> None:
3460
"""
35-
Update options in the dimension selector from currently selected layer.
61+
Update range and enabled status of the slice selectors, and the value
62+
of the z slice selector.
3663
"""
37-
dims = ["x", "y", "z"]
38-
self.dim_selector.clear()
39-
self.dim_selector.addItems(dims[0 : self.layer.data.ndim])
64+
# Update min/max
65+
for i, dim in enumerate(_dims):
66+
self.slice_selectors[dim].setRange(0, self.layer.data.shape[i])
67+
68+
# The z dimension is always set by current z in the viewer
69+
self.slice_selectors["z"].setValue(self.current_z)
70+
self.slice_selectors[self.current_dim].setEnabled(False)
71+
72+
def draw(self) -> None:
73+
x = np.arange(self.layer.data.shape[self.current_dim_index])
74+
75+
slices = []
76+
for d in _dims:
77+
if d == self.current_dim:
78+
# Select all data along this axis
79+
slices.append(slice(None))
80+
else:
81+
# Select specific index
82+
val = self.selector_values[d]
83+
slices.append(slice(val, val + 1))
84+
85+
slices = slices[::-1]
86+
y = self.layer.data[tuple(slices)].ravel()
87+
88+
self.axes.plot(x, y)
89+
self.axes.set_xlabel(self.current_dim)
90+
self.axes.set_title(self.layer.name)

0 commit comments

Comments
 (0)