Skip to content
Open
Show file tree
Hide file tree
Changes from all 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 usually inherits layer units when they are set. If inference fails it can fall back to a dimensionless label, and if displayed axes mix dimensionalities it uses the last displayed axis unit with a warning. You can control its appearance and fixed length from the viewer. See the [units guide](units-guide) for more information.
- 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
89 changes: 89 additions & 0 deletions docs/guides/units.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
(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`, combining into a
spatial transformation with dimensions that carry physical meaning.
All layers of napari contain these transforms 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.

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.

If napari cannot infer a consistent layer-list unit, the scale bar becomes
dimensionless. There is also one important special case: the scale bar label
corresponds to the last displayed axis. If the displayed axes do not all have
the same dimensionality, napari will warn that only the last displayed axis unit is being used.

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