Surface#

In this document, you will learn about the napari surface layer, including how to display surface data and edit the properties of surfaces like the contrast, opacity, colormaps and blending mode. You will also understand how to add and manipulate surfaces mostly from the console. There are a few slider controls that are available in the GUI.

For more information about layers, refer to Layers at a glance.

Note

Surface layers can be created only programmatically, i.e. in the console, or using a script, not from the GUI. Please refer to A simple example and use the code there to add a surface layer first, then explore the GUI controls.

When to use the surface layer#

The surface layer allows you to display a precomputed surface mesh: a set of vertices connected into triangular faces. Each vertex can optionally carry a value that is mapped through a colormap to color the surface. The exact data format is described in the Surface data section.

A simple example#

You can create a new viewer with napari.Viewer() and add a surface using the add_surface() method.

A simple example of viewing a surface follows. You can copy and paste these statements into the napari console to see how they work:

import napari
import numpy as np

vertices = np.array([[0, 0], [0, 20], [10, 0], [10, 10]])
faces = np.array([[0, 1, 2], [1, 2, 3]])
values = np.linspace(0, 1, len(vertices))
surface = (vertices, faces, values)

viewer = napari.Viewer()
viewer.add_surface(surface)  # add the surface

Hide code cell source

from napari.utils import nbscreenshot

nbscreenshot(viewer, alt_text="A viewer with a surface")

GUI controls for the surface layer#

Once you have created a surface layer programmatically, the following GUI controls are available in the viewer:

Controls related to contrast limits, auto-contrast, gamma, and colormap are only available when the surface color is computed from vertex_values. If you provide vertex_colors, napari uses those colors directly and disables those controls because they no longer affect rendering. When a texture is present, napari multiplies the texture color by the underlying surface color.

  • Buttons

    • Pan/zoom - image: Pan/zoom tool is the default mode of the layer and supports panning and zooming. Press the 1 key when the layer is selected to use this mode.

    • Transform - image: Transform enables you to rotate, scale, or translate the layer. Note: at present this feature is limited to 2D viewer display mode. To reset the transformation, you can Option/Alt-click the transform button (a confirmation dialog will open to confirm the reset). Press the 2 key when the layer is selected to use this mode.

  • Controls

    • Opacity - use this slider control to assign opacity from 0 to 1.00 where 0 is transparent and 1.00 is completely opaque.

    • Contrast Limits - click and slide the dots on either end of the slider bar to adjust upper and lower contrast limits.

    • Auto-contrast - choose once or continuous.

    • Gamma - Click on the oval on the gamma slider bar and adjust it to any value between 0.20 and 2.00. Gamma correction or gamma is a nonlinear operation used to encode and decode luminance or tristimulus values in video or still image systems.

    • Colormap - select a value from the dropdown list.

    • Blending - Choose opaque, translucent, translucent no depth, or additive from the dropdown. Refer to the Blending layers section of Layers at a glance for an explanation of each type of blending.

    • Shading - Choose none, flat, or smooth from the dropdown.

Arguments of add_surface#

add_surface() accepts the following layer-creation parameters.

help(napari.Viewer.add_surface)

Surface data#

The data for a surface layer can be given as either a 2-tuple (vertices, faces) or a 3-tuple (vertices, faces, vertex_values).

  • The vertices are an NxD array of N vertices in D coordinates.

  • The faces are an Mx3 integer array of the indices of the triangles making up the faces of the surface.

  • The optional vertex values are a length N array of scalar values to associate with each vertex for colormap-based rendering. They can also have additional leading dimensions (for example, a time series), in the form (D1, D2, ..., N), which napari treats as extra dimensions of the layer. If you omit vertex_values, napari fills them with ones, so the default underlying surface color is white.

How surface colors are computed#

  • vertex_values are mapped through the selected colormap. contrast limits, auto-contrast, and gamma all operate on this scalar-coloring path.

  • vertex_colors provide direct per-vertex colors and override any color that would otherwise come from vertex_values. When vertex_colors are present, the GUI disables the scalar-coloring controls because they do not affect the rendered surface.

  • texture plus texcoords multiplies the texture color by the underlying surface color. If that underlying color comes from vertex_values, the scalar-coloring controls still affect the result. If it comes from vertex_colors, they do not.

3D rendering#

All layers can be rendered in both 2D and 3D. One of the viewer buttons at the bottom of the left panel can toggle between these 2 modes. When in 2D, the button looks like this: image: 2D/3D button, ready to switch to 3D mode. When in 3D, the button looks like this: image: 2D/3D button, ready to switch to 2D mode.

The number of dimensions sliders will be 2 or 3 less than the total number of dimensions of the layer, allowing you to browse volumetric timeseries data and other high dimensional data. An example is these brain surfaces rendered in 3D:

Working with colormaps#

The same colormaps available for the image layer are also available for the surface layer. napari supports any colormap that is created with vispy.color.Colormap. We provide access to some standard colormaps that you can set using a string of their name. Please see the list below.

list(napari.utils.colormaps.AVAILABLE_COLORMAPS)

Passing any of these as keyword arguments will set the colormap of that surface. You can also access the current colormap through the layer.colormap property which returns a tuple of the colormap name followed by the vispy colormap object. You can list all the available colormaps using layer.colormaps.

It is also possible to create your own colormaps using vispy’s vispy.color.Colormap object, see it’s full documentation here. For more detail see the image layer guide.

Adjusting contrast limits#

The vertex values of the surface layer get mapped through its colormap according to values called contrast limits. These are a 2-tuple of values defining how what values get applied the minimum and maximum of the colormap and follow the same principles as the contrast_limits described in the image layer guide. They are also accessible through the same keyword arguments, properties, and GUI layer controls as in the image layer.

These controls only apply when the surface is colored from vertex_values. That includes textured surfaces whose texture is multiplied by a color derived from vertex_values. They do not apply when the surface is colored directly by vertex_colors.