napari: a fast, interactive, multi-dimensional image viewer for python
We're happy to announce the release of napari 0.4.19! napari is a fast, interactive, multi-dimensional image viewer for Python. It's designed for browsing, annotating, and analyzing large multi-dimensional images. It's built on top of Qt (for the GUI), vispy (for performant GPU-based rendering), and the scientific Python stack (numpy, scipy).
For more information, examples, and documentation, please visit our website: https://napari.org/stable/
This release mostly contains a lot of bug fixes and performance improvements. But look out for 0.5.0, coming to a software repository near you — we expect to release a lot of new features then!
#3308 closed many long-standing bugs in the handling of colors in the Labels layer: the color swatch in the Labels controls now always matches the color on the canvas, direct color mapping with thousands of colors works fine, and shuffling colors (when two touching labels coincidentally had the same color) is now much more likely to map them to different colors. 🎨🚀🚀🚀
Unfortunately, the fix turned out to have rather terrible consequences for the rendering performance of 3D Labels, and each time we fixed one thing something else reappeared in a game of bug fix whack-a-mole that any programmer would recognize. A great many fixes later (#6411, #6439, #6459, #6460, #6461, #6467, #6479, #6520, #6540, #6571, #6580, #6596, #6602, #6607, #6616, #6618) — thank you for your patience! 😅 — Labels are faster than ever and color accurate. But, to get the best performance, if you can use 8- or 16-bit integers as your data type, you should do so, and if not, you should install numba, a just-in-time compiler for numerical code in Python. (Ultimately, the data sent to the GPU will be 8- or 16-bit, so if you use a larger data type, you will pay some conversion cost.)
These improvements in color handling are accompanied by updates to the Labels API. You can now easily set a specific color cycle for Labels data. For example, to use the famous Glasbey look-up table/color cycle, you can combine the glasbey
Python package with the new CyclicLabelColormap
API:
import glasbey
from napari.utils.colormaps import CyclicLabelColormap
# ...
labels_layer = viewer.add_labels(
segmentation, colormap=CyclicLabelColormap(glasbey.create_palette(256))
)
See the "Deprecations" section below for more information on the new API. (#6542)
Yes, this is the colors update! 🌈
Making image layers with linear colormaps using custom colors is easier than ever! You can just do viewer.add_image(data, color='turquoise')
to get a black-to-turquoise linear colormap for that image. For the full list of colors available, see the VisPy color dict (#6102). You can also pass in an RGB hex color prefixed with #
, as in napari.imshow(data, colormap=
#88ff1a)
.
(For an amusing side note, though, check out the API Changes note related to this PR. 😅)
If you were worried about those pesky "public access to qt_viewer
will be removed" warnings, fret not! Its removal has been postponed until at least 0.6.0! We want to spend more time working with the community to ensure your use case is supported before pulling out the rug. 🤝 If you are using the qt_viewer
because we don't have another public API to do what you need, please raise an issue so we can make sure your use case is supported before we remove it. (#6283)
Finally, although we still use pydantic 1.0 objects internally, napari installs correctly with both pydantic v1 and pydantic v2. If you wanted to upgrade your napari library or plugin to use Pydantic 2, now you can!
Note though, for 0.4.19, the napari bundled app still ships with Pydantic 1.x. However, we will bundle v2 starting with 0.5.0, so if you use Pydantic internally, now is a good time to check that you are compatible either v2 or both v1 and v2 (#6358).
As always, napari is developed by the community, for the community. We want to hear from you and help you get your napari visualization and/or plugin use done faster! And if napari is missing something you need, we can help you add it! So please remember to ask questions on image.sc, join our Zulip chat room, come to our community meetings, or tag us on Mastodon!
Read on for the full list of changes that went into this release.
np
to console predefined variables (napari/napari#6314)pydantic.v1
(napari/napari#6358)app_user_model_id
to bundle shortcut) (napari/napari#6056)ScreenshotDialog
widget and fixes (napari/napari#6057)examples/multiple_viewer_widget.py
copy layer logic (napari/napari#6162)QLabeledRangeSlider
style rule to prevent labels from being cut off (napari/napari#6180)ShapeList.outline
validations for int
/list like argument and add a test (napari/napari#6215)changing
event to EventedDict
(napari/napari#6268)breakpoint()
function after console import (napari/napari#6443)triangle
is installed (napari/napari#6488)changed
event emission (napari/napari#6611)Labels.data_setitem
setting of view by taking dims order into account (napari/napari#6616)#6102 added the ability to set
linear colormaps from black to a named color by using colormap="color-name"
syntax. It turns out that "orange" is both the name of a
white-to-orange colormap in VisPy, and one of the color names in the color
dictionary, therefore implicitly a black-to-orange colormap! We decided to use
the new, color-name behavior in this update. So if you are wondering why your
imshow(data, colormap='orange')
calls look different — this is why.
In #6178, the "action" type of events emitted when editing Shapes or Points was changed to be more granular. The types are no longer "add", "remove", and "change", but "adding", "added", "removing", "removed", "changing", and "changed". This gives listeners more control over when to take action in response to an event.
#6542 made a number of
deprecations to the Labels API to simplify it. Rather than having color-related
properties strewn all over the layer, color control is moved strictly to the
layer's colormap
. Here is the full list of deprecated attributes and their
replacements:
layer.num_colors
becomes len(layer.colormap)
.
layer.num_colors = n
becomes layer.colormap = label_colormap(n)
.napari.utils.colormaps.LabelColormap
is deprecated and has been renamed to
napari.utils.colormaps.CyclicLabelColormap
.layer.color
becomes layer.colormap.color_dict
.
layer.color = color_dict
becomes
layer.colormap = DirectLabelColormap(color_dict)
.layer._background_label
is now at
layer.colormap.background_value
.layer.color_mode
is set by setting the colormap using the
corresponding colormap type (CyclicLabelColormap
or DirectLabelColormap
;
these classes can be imported from napari.utils.colormaps
.).seed
: was only used for shifting labels around in [0, 1]. It is
superseded by layer.new_colormap()
which was implemented in
#6460.myModal
to eventDetailBackground
in meetings schedule (napari/docs#343)certifi
, dask
, fsspec
, hypothesis
, imageio
, ipython
, pint
, qtconsole
, rich
, virtualenv
(napari/napari#5788)dask
, hypothesis
, torch
(napari/napari#5835)app-model
, certifi
, dask
, hypothesis
, jsonschema
, npe2
, pydantic
, pyqt6
, pyyaml
, tifffile
, virtualenv
, xarray
, zarr
(napari/napari#6007)rich
(napari/napari#6105)dask
, hypothesis
, jsonschema
, numpy
, pygments
, rich
, superqt
(napari/napari#6124)test_link_layers_with_images_then_loaded_not_linked
test (napari/napari#6385)app-model
, babel
, certifi
, dask
, fsspec
, hypothesis
, imageio
, ipython
, jsonschema
, lxml
, magicgui
, matplotlib
, numba
, numpy
, pandas
, pillow
, pint
, psutil
, psygnal
, pydantic
, pygments
, pyqt6
, pytest-qt
, qtconsole
, rich
, scipy
, tensorstore
, tifffile
, torch
, virtualenv
, wrapt
, xarray
(napari/napari#6559)dask
, hypothesis
, ipython
, jsonschema
, lxml
, npe2
, numpy
, pillow
, psutil
, pytest
, scipy
, tensorstore
, toolz
, xarray
(napari/napari#6608)hypothesis
, pydantic
, tifffile
(napari/napari#6630)There are 5 new contributors for this release: