Proper way to erase all data in a layer?

I’ve been running into an issue, in which in previous versions of napari, I could reliably clear a shapes layer using
layer.data = []
or
layer.data = np.empty((0, 2))

This worked, although I’ve always felt a little uncomfortable with this, as it feels like I should be using a method as opposed to directly tampering with data. Is there a “correct” way to clear a layer? (I would prefer not to remove the layer entirely).

As of upgrading to napari 0.3.6, I’m getting a new error when I try to clear out data from a shapes layer (points layer seems okay). The relevant section of my code looks like:

for layer in viewer.layers:  # erase all annotation layers
    layer_type = layer.as_layer_data_tuple()[2]
    if layer_type == 'points':
        layer.data = np.empty((0, 2))
    elif layer_type == 'shapes':
        layer.data = []

which used to work, but now produces this error:

  File "my_prog.py", line 402, in annotate
    layer.data = []
  File "/home/nate/.pyenv/versions/histo_new/lib/python3.7/site-packages/napari/layers/shapes/shapes.py", line 512, in data
    self.add(data, shape_type=shape_type)
  File "/home/nate/.pyenv/versions/histo_new/lib/python3.7/site-packages/napari/layers/shapes/shapes.py", line 1432, in add
    if np.array(data[0]).ndim == 1:
IndexError: list index out of range

A minimal example would be something like this:

import napari
import numpy as np
viewer = napari.Viewer()
viewer.add_shapes(np.random.rand(10,5,2)*100, shape_type='polygon')
viewer.layers['Shapes'].data = []  # this used to work in 0.3.5!

Any suggestions as to 1) the appropriate way to clear data, and in lieu of that 2) ideas about why this is no longer working would be greatly appreciated. Thanks!

Interesting, this seems like an unintended regression! I don’t think we have any established best way to clear data from points/ shapes or unit tests for that behaviour, but we should add some!!

I think layer.data = [] is quite natural, particularly for Shapes, where data is a list of arrays. One awkward thing though concerns the “dimensionality” of the layer and whether that gets lost or preserved in these cases. Something like [np.empty((0, 2))] should work too, but it’s not so user friendly.

I’m about to sign off for the night but can think about this more tomorrow. Maybe @kevinyamauchi has suggestions here?

1 Like

Thanks so much for your super fast response!! At previous suggestions from @jni , I initialize all layers to the correct dimensionality that way with empty numpy arrays of defined dimensionality, and I agree, it makes more sense to clear them that way. However, I get different errors if I use either of the following:


viewer.layers['Shapes'].data = [np.empty((0,2))]
[]
Traceback (most recent call last):

  File "<ipython-input-29-9b336ebeff45>", line 1, in <module>
    viewer.layers['Shapes'].data = [np.empty((0,2))]

  File "/home/nate/.pyenv/versions/3.7.4/envs/histo_new/lib/python3.7/site-packages/napari/layers/shapes/shapes.py", line 512, in data
    self.add(data, shape_type=shape_type)

  File "/home/nate/.pyenv/versions/3.7.4/envs/histo_new/lib/python3.7/site-packages/napari/layers/shapes/shapes.py", line 1467, in add
    z_index=z_index,

  File "/home/nate/.pyenv/versions/3.7.4/envs/histo_new/lib/python3.7/site-packages/napari/layers/shapes/shapes.py", line 1664, in _add_shapes
    ndisplay=self.dims.ndisplay,

  File "/home/nate/.pyenv/versions/3.7.4/envs/histo_new/lib/python3.7/site-packages/napari/layers/shapes/_shapes_models/rectangle.py", line 36, in __init__
    self.data = data

  File "/home/nate/.pyenv/versions/3.7.4/envs/histo_new/lib/python3.7/site-packages/napari/layers/shapes/_shapes_models/rectangle.py", line 60, in data
    {len(data)} provided."""

ValueError: Data shape does not match a rectangle.
                             Rectangle expects four corner vertices,
                             0 provided.

or


viewer.layers['Shapes'].data = np.empty((0,0,2))
Traceback (most recent call last):

  File "<ipython-input-31-6e9a832b0c14>", line 1, in <module>
    viewer.layers['Shapes'].data = np.empty((0,0,2))

  File "/home/nate/.pyenv/versions/3.7.4/envs/histo_new/lib/python3.7/site-packages/napari/layers/shapes/shapes.py", line 512, in data
    self.add(data, shape_type=shape_type)

  File "/home/nate/.pyenv/versions/3.7.4/envs/histo_new/lib/python3.7/site-packages/napari/layers/shapes/shapes.py", line 1432, in add
    if np.array(data[0]).ndim == 1:

IndexError: index 0 is out of bounds for axis 0 with size 0