# Controlling dimensionality of napari point/shape layers?

When instantiating a new shapes or points layer, the dimensionality of the data seems to depend on the current state of the viewer.

For example, if I make a 2D image layer and then a shapes layer, the shape data is 2D:

``````import napari
import numpy as np

with napari.gui_qt() as app:
viewer = napari.Viewer()
image = np.random.rand(100,100)

# now i manually draw a line in the viewer in the shape layer

print(viewer.layers['shape_layer'].data)
# [array([[ 17.64782677, -12.67391434],
#   [ 66.43043749, 109.18696027]])]
``````

However, if the initial image layer has 3D data, then the shapes layer is 3D:

``````with napari.gui_qt() as app:
viewer = napari.Viewer()
image = np.random.rand(5,100,100)

# now i manually draw a line in the viewer in the shape layer

print(viewer.layers['shape_layer'].data)
# [array([[  0.        ,  20.35895121, -18.13110399],
#   [  0.        ,  67.30289359, 109.57233247]])]
``````

Is there a way to ensure that a layer contains only data of a given dimension? Iâ€™d love to be able to create layers with strict dimensionality.

Thereâ€™s an ndim parameter Iâ€™ve seen in the base layer class (https://napari.org/docs/api/napari.layers.base.html?highlight=ndim), but Iâ€™m not clear if/how to use that.

Any help would be greatly appreciated!

1 Like

Hi @naten7k!

With points, the input data shape is npoints x ndim, so to get an empty layer of the right dimensionality, you pass in an empty â€śpointsâ€ť array of shape 0, ndim:

``````pts_layer = viewer.add_points(np.empty((0, 3)))  # 3D points
``````

For shapes, the shape of the array is nshapes x npoints x ndim, so you actually need to pass in an array of shape (0, 0, ndim), and then you get the dimensionality you want:

``````shp_layer = viewer.add_shapes(np.empty((0, 0, 4)))  # 4D shapes layer
print(shp_layer.ndim)  # prints 4
``````

Hopefully that gets you started. I must agree that this is not the most intuitive and certainly is not obvious in the current docs â€” I had to go look at the source code to figure it out! Perhaps an `ndim` keyword argument would be better.

1 Like

@naten7k I created an issue to discuss this option as well as other alternatives. Thanks for bringing this to our attention!

1 Like

Thanks @jni! This is perfect.

1 Like