Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ subtrees:
- entries:
- file: guides/3D_interactivity
- file: guides/axis-names
- file: guides/units
- file: guides/handedness
- file: guides/triangulation
- file: guides/rendering
Expand Down
2 changes: 1 addition & 1 deletion docs/getting_started/viewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ In napari there are two main types: canvas overlays - which are locked in positi

The viewer gives access to a few such overlays:

- Scale bar (canvas overlay, accessible via `viewer.scale_bar`): you may set its unit, length, and other parameters.
- Scale bar (canvas overlay, accessible via `viewer.scale_bar`): it displays distances in world coordinates for the displayed scene. The scale bar inherits layer units when they are set, and otherwise falls back to pixels. You can control its appearance and fixed length from the viewer.
- Axes (scene overlay, accessible via `viewer.axes`): displays basis axes at the origin.
- Text Overlay (canvas overlay, accessible via `viewer.text_overlay`): displays arbitrary text on the canvas.

Expand Down
3 changes: 3 additions & 0 deletions docs/guides/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ while you wait for a computation to finish, you may benefit from reading about

If you are interested in using napari to explore 3D objects, see {ref}`3d-interactivity`.

To understand how physical units propagate from layers into rendering and the
scale bar, see {ref}`units-guide`.

To understand how napari produces a 2- or 3-dimensional render in the canvas
from layers’ n-dimensional array-like data, check out the {ref}`dedicated guide on rendering in napari <rendering>`.

Expand Down
84 changes: 84 additions & 0 deletions docs/guides/units.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
(units-guide)=

# Scale and unit-aware rendering

Units in napari describe the physical meaning of each layer axis. They work
alongside layer transforms such as `scale` and `translate`, but they answer a
different question: `scale` informs about the spacing of the data, while `units`
inform the meaning behind each scale value. All layers of napari contain both
`scale` and `units` metadata, and they work together to determine how the layer is
rendered and how it interacts with other unit-aware features such as the scale bar.
Comment thread
TimMonko marked this conversation as resolved.
Outdated

For interactive editing, the
[napari-metadata](https://napari.org/napari-metadata/) plugin can expose
layer scale and units in a dock widget.

## Scale and units live on layers

Scale and units are layer metadata. You can provide them when creating a layer or update
them later from Python:

```python
import numpy as np
import napari

viewer = napari.Viewer()
layer = viewer.add_image(
np.zeros((16, 32, 64)),
scale=(4, 0.25, 0.25),
units=('s', 'um', 'um'),
)

layer.units = ('usec','nm', 'nm') # update units later
```

In this example, each pixel of the image layer is spaced by `0.25` micrometers along both axes.
The scale is used to transform each layer from its data coordinates into rendered world coordinates,
so both vector-based layers (points, shapes, vectors, tracks) and raster-based layers (images, labels)
are affected by scale and units.

Units can be any valid [Pint](https://pint.readthedocs.io/en/stable/) unit,
of which [there are a plethora](https://github.com/hgrecco/pint/blob/master/pint/default_en.txt)
to serve many different disciplines.
Pint also has logic to disambiguate unit names, for example,
`'micrometer'`, `'um'`, and `'µm'` are all valid and will equate to `'µm'` in napari.

If you do not set units, napari assumes pixels.
To set *no* units, use `layer.units = ('dimensionless',...)`.

## When units are consistent across layers

napari can use units to render layers in the same physical space even when the
numerical scale values are different. This matters when, for example, one layer
is stored in nanometers and another is stored in micrometers.

The gallery example {ref}`sphx_glr_gallery_units_impact_rendering.py` shows
this directly: two image layers use different units and different scale values,
but napari still aligns them in the same world coordinate system.

## How the scale bar gets its units

The scale bar is a viewer overlay, but its label is tied to the same world
coordinates used to render the scene.
If units are consistent across layers, the scale bar will automatically display
the correct units and length to scale. If you do not provide units, napari falls
back to pixels.

The gallery example {ref}`sphx_glr_gallery_scale_bar.py` focuses on scale bar
appearance and layout. The gallery example
{ref}`sphx_glr_gallery_units_impact_rendering.py` focuses on unit-aware world
space. Taken together, they currently provide the clearest picture of how scale
bar display and layer units interact.

## What units do not do

Units do not rename axes. Axis labels and units are related metadata, but they
solve different problems:

- axis labels describe what an axis represents, such as `time`, `z`, `y`, or
`x`
- units describe the measurement system on that axis, such as `s`, `nm`, or
`pixel`

For more about axis labels, broadcasting, and how layer metadata maps onto the
viewer, see {ref}`axis-names`.
Loading