napari
napari copied to clipboard
Slicing does not always occur when changing points data
🐛 Bug
Changing a points layer's data programmatically can cause the viewer to get in a state where no data is presented, as demonstrated in the following video.
https://github.com/napari/napari/assets/2608297/cd95a793-9203-4ee8-a5c9-8d437189ebdc
I think we need two conditions for this particular failure (similar to #6199).
- The data is changed in a way that changes the extent of the layer.
- The current slicing plane defined by
Dims.point
is no longer in the extent of the layer.
I don't see an obvious way to recover from this state either through the GUI or through the public API. One way to do it with the private API is to call viewer._update_layers()
.
Note that Dims.point
is changed, but this is done in the root validator of Dims
due to the change in Dims.range
, so no event is emitted and thus no slicing occurs. Therefore, this probably occurs for other layer types.
To Reproduce
Here's a test that fails.
def test_last_point_is_visible_in_viewport():
viewer = ViewerModel()
# Removing the last point while viewing it should cause
# us to view the first point due to the layer's new extent.
points = viewer.add_points([[0, 1, 1], [1, 2, 2]])
viewer.dims.set_point(0, 1)
assert viewer.dims.point[0] == 1
np.testing.assert_array_equal(points._indices_view, [1])
points.data = [[0, 1, 1]]
assert viewer.dims.point[0] == 0
# This one passes.
np.testing.assert_array_equal(points._indices_view, [0])
viewer.layers.remove(points)
# Removing the first point while viewing it should cause us
# to view the last point due to the layer's new extent.
points = viewer.add_points([[0, 1, 1], [1, 2, 2]])
viewer.dims.set_point(0, 0)
assert viewer.dims.point[0] == 0
np.testing.assert_array_equal(points._indices_view, [0])
points.data = [[1, 2, 2]]
assert viewer.dims.point[0] == 1
# This one fails
np.testing.assert_array_equal(points._indices_view, [0])
Expected behavior
Slicing should occur when points data is changed in this way.
Environment
napari: 0.5.0a2.dev391+gb29f3ed4d.d20230814
Platform: macOS-10.16-x86_64-i386-64bit
System: MacOS 13.5
Python: 3.9.6 (default, Jul 30 2021, 09:31:09) [Clang 10.0.0 ]
Qt: 5.15.2
PyQt5: 5.15.4
NumPy: 1.25.1
SciPy: 1.10.1
Dask: 2023.6.1
VisPy: 0.13.0
magicgui: 0.7.0rc1.dev6+ga3bdc90
superqt: 0.5.3
in-n-out: 0.1.5
app-model: 0.1.4
npe2: 0.7.0
OpenGL:
- GL version: 2.1 INTEL-20.6.4
- MAX_TEXTURE_SIZE: 16384
Screens:
- screen 1: resolution 1920x1080, scale 1.0
Settings path:
- /Users/asweet/Library/Application Support/napari/napari-dev-pyqt5_cc8ffd7cdbca034eda3f67dc1b401303ece224df/settings.yaml
Additional context
Coming from https://github.com/napari/napari/pull/4819 which contained a fix at one commit, but one which was not quite precise enough (i.e. it also caused slicing to occur when unneeded.