Skip to content

napari viewer plugin

Open an OME-ZARR image and overlay the labels produced by tile_process as a napari Labels layer in a single call. Requires the optional napari extra (pip install "patchworks[napari]").

patchworks.plugins.napari.view_in_napari(image: Union[da.Array, str, Path], labels: Union[da.Array, str, Path, None] = None, *, channel: int | None = 0, labels_component: str = 'labels', image_name: str = 'image', labels_name: str = 'labels', show: bool = True, **add_image_kwargs: Any)

Open image in napari and overlay labels as a Labels layer.

Parameters:

Name Type Description Default
image (Array, str or Path)

OME-ZARR store (multi-scale aware), any bioio-readable file, or an in-memory array.

required
labels (Array, str, Path or None)

Label array to overlay. A plain .zarr store written by tile_process is read from its labels_component; an OME-ZARR pyramid is shown multi-scale. None (default) auto-loads every label image stored inside the OME-ZARR under labels/<name>/ — the place tile_process writes them by default — each as its own Labels layer. (Falls back to image-only if there are none.)

None
channel int or None

Channel to display from the image (None keeps all channels).

0
labels_component str

Array name inside a plain-zarr label store (default "labels", matching tile_process's output_component).

'labels'
image_name str

Layer names shown in napari.

'image'
labels_name str

Layer names shown in napari.

'image'
show bool

Start the napari event loop (blocking). Set False in scripts/tests that manage the loop themselves.

True
**add_image_kwargs Any

Extra keyword arguments forwarded to viewer.add_image (e.g. colormap, contrast_limits).

{}

Returns:

Type Description
Viewer

The viewer instance (useful when show=False).

Examples:

>>> view_in_napari("scan.zarr")  # auto-loads scan.zarr/labels/*
Source code in src/patchworks/plugins/napari.py
def view_in_napari(
    image: Union[da.Array, str, Path],
    labels: Union[da.Array, str, Path, None] = None,
    *,
    channel: int | None = 0,
    labels_component: str = "labels",
    image_name: str = "image",
    labels_name: str = "labels",
    show: bool = True,
    **add_image_kwargs: Any,
):
    """Open *image* in napari and overlay *labels* as a Labels layer.

    Parameters
    ----------
    image : da.Array, str or Path
        OME-ZARR store (multi-scale aware), any bioio-readable file, or an
        in-memory array.
    labels : da.Array, str, Path or None
        Label array to overlay. A plain ``.zarr`` store written by
        ``tile_process`` is read from its ``labels_component``; an OME-ZARR
        pyramid is shown multi-scale. ``None`` (default) **auto-loads** every
        label image stored inside the OME-ZARR under ``labels/<name>/`` — the
        place ``tile_process`` writes them by default — each as its own Labels
        layer. (Falls back to image-only if there are none.)
    channel : int or None, optional
        Channel to display from the image (``None`` keeps all channels).
    labels_component : str, optional
        Array name inside a plain-zarr label store (default ``"labels"``,
        matching ``tile_process``'s ``output_component``).
    image_name, labels_name : str, optional
        Layer names shown in napari.
    show : bool, optional
        Start the napari event loop (blocking). Set ``False`` in scripts/tests
        that manage the loop themselves.
    **add_image_kwargs
        Extra keyword arguments forwarded to ``viewer.add_image``
        (e.g. ``colormap``, ``contrast_limits``).

    Returns
    -------
    napari.Viewer
        The viewer instance (useful when ``show=False``).

    Examples
    --------
    >>> view_in_napari("scan.zarr")  # auto-loads scan.zarr/labels/*  # doctest: +SKIP
    """
    napari = _require_napari()

    img = _resolve_image(image, channel)
    viewer = napari.Viewer()
    viewer.add_image(
        img,
        name=image_name,
        multiscale=isinstance(img, list),
        **add_image_kwargs,
    )

    if labels is not None:
        lab = _resolve_labels(labels, labels_component)
        viewer.add_labels(lab, name=labels_name)
    elif _is_zarr(image):
        # No labels given → auto-overlay every label image stored inside the
        # OME-ZARR under labels/<name>/ (the default place tile_process writes
        # them), each as its own multi-scale Labels layer.
        for name in _inner_label_names(image):
            levels = _multiscale_levels(f"{image}/labels/{name}", None)
            lab = [lvl.astype("int32") for lvl in levels]
            viewer.add_labels(lab if len(lab) > 1 else lab[0], name=name)
            logger.info("auto-loaded labels/%s from %s", name, image)

    if show:
        napari.run()
    return viewer