Skip to content

Releases: napari/napari

0.4.19.post1

28 Feb 16:49
daf7205
Compare
Choose a tag to compare
v0.4.19.post1

Add dummy release notes

0.4.19

01 Feb 09:37
bd47bf0
Compare
Choose a tag to compare

napari 0.4.19

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/

Highlights

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!

BIG improvements to the Labels layer

#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)

More on colormaps!

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. 😅)

Some technical stuff

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).

Onwards!

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.

New Features

Improvements

Performance

  • Use a shader for low discrepancy label conversion (napari/napari#3308)
  • Fix lagging 3d view for big data in auto color mode (napari/napari#6411)
  • Fix cycle in _update_draw/_set_highlight for Points and Shapes (high CPU background usage) (napari/napari#6425)
  • Update performance and reduce memory usage for big Labels layer in direct color mode (napari/napari#6439)
  • Add _data_to_texture method to LabelColormap and remove caching of (u)int8 and (uint16) (napari/napari#6602)

Bug Fixes

Read more

0.4.19rc8

30 Jan 09:37
1d37904
Compare
Choose a tag to compare
0.4.19rc8 Pre-release
Pre-release
Fix rendering of vertexes of shape layers with small scale (#6628)

# References and relevant issues
Bug spotted in context #6627 

# Description

After changes in #5802 the vertex border is very thick:

![Zrzut ekranu z 2024-01-29
15-09-03](https://github.com/napari/napari/assets/3826210/4f2ca013-b4cc-4b86-bd2f-7e668895846e)

This PR reverts this change as Marker's size is in absolute unit, not
data unit.


![image](https://github.com/napari/napari/assets/3826210/d087d373-3f31-4258-bba9-ffe7c34458bf)


Script for reproduce:

```python
import napari
import numpy as np


s = (0.01, 0.005, 0.005)
s = (0.005, 0.005, 0.005)
s = (0.01, 0.01, 0.01)
s = (0.1, 0.1, 0.1)
# s = (1, 1, 1)
viewer = napari.Viewer()
layers = viewer.open_sample("napari", "cells3d")
for l in layers:
    l.scale = s

shapes = viewer.add_shapes(
    np.array(
        [
            [29.0, 130.70802005, 86.37901572],
            [29.0, 130.70802005, 137.70733652],
            [29.0, 182.32797904, 137.70733652],
            [29.0, 182.32797904, 86.37901572],
        ]
    ),
    scale=s,
)
shapes.mode = "select"
viewer.dims.current_step = (29, 0, 0)
viewer.reset_view()

napari.run()
```

0.4.19rc7

28 Jan 23:41
bb7b822
Compare
Choose a tag to compare
0.4.19rc7 Pre-release
Pre-release
Fix points `changed` event emission (#6611)

# References and relevant issues
This PR fixes an issue reported on
[forum.image.sc](https://forum.image.sc/t/napari-how-to-distinguish-between-shape-added-removed-by-user-and-back-end/78529/12).
It s one of the latest posts.

# Description
This PR moves the event emission when a point has changed from `_move`
in the `Points` layer to `select` in `_points_mouse_bindings`. This
because in `_move` events where emitted during moving and then the last
event to be emitted when the dragging stops and the user releases the
mouse does not have `selected_indices`. For example below, move the
point and then check console output once drag is finished. You see the
action is `CHANGED` but `data_indices` is empty while it should be `(0)`

```python
import napari

def check_call(event):
    print(event.action)
    print(event.data_indices)


viewer = napari.Viewer()
layer = viewer.add_points([5,5])
layer.events.data.connect(check_call)
napari.run()
```

The event now is only emitted when dragging stops and the output for the
example is now as expected. The downside is that it is more challenging
to test this as `Mock` with `layer.data.events` does not emit anything
now by purely using the `_move` method. This still needs to be fixed.

---------

Co-authored-by: Grzegorz Bokota <bokota+github@gmail.com>

0.4.19rc6

27 Jan 18:59
9e1778d
Compare
Choose a tag to compare
0.4.19rc6 Pre-release
Pre-release
Bug fixes to multiple issues with linked layers (#6623)

# References and relevant issues
Closes https://github.com/napari/napari/issues/6619

# Description
While testing https://github.com/napari/napari/pull/6622 I noted a
number of issues with linked layers:
1) a removed layer remains linked (this was also reported in
https://github.com/napari/napari/issues/6619 )
2) if two points layers are linked and you try to add a point to either
one you get:
`ValueError: The truth value of a DataFrame is ambiguous. Use a.empty,
a.bool(), a.item(), a.any() or a.all().`
3) if you have a Labels layer linked to points, shapes, image and try to
paint, you get:
`ValueError: 'paint' is not a valid Mode`
4) if you have a Shapes layer linked to any other layer and try to draw
a shape, you get:
`ValueError: 'add_rectangle' is not a valid Mode`

This is a PR to fix them.
- unlink layers before removing from layer list
- add equality operator for pandas DF, so that `pick_equality_operator`
works for Points
- add things to the `exclude` list that are problematic because:
	- they either are data related (e.g. features/properties)
- depend on number of <data elements> (e.g. edge_width, face_color,
edge_color)
	- are not compatible between layers (e.g. mode)

I've added tests for:
- unlinking of removed layers (this fails on main)
- the pandas equality operator
- linked points layers (this fails on main)
- linked layer modes (this fails on main)

---------

Co-authored-by: Grzegorz Bokota <bokota+github@gmail.com>

0.4.19rc5

24 Jan 16:12
f1a39b8
Compare
Choose a tag to compare
0.4.19rc5 Pre-release
Pre-release
Fix `Labels.data_setitem` setting of view by taking dims order into a…

…ccount (#6616)

closes #6615

In #6607, we started painting into both the data and the slice view.
(And this was already happening and broken when painting into lazy
arrays such as zarr and dask, #6112.) However, when setting the view we
need to take into account the axis ordering used when slicing (some axes
may be transposed). This manifested as an index error in #6615.

In this PR, we add an `indices_order` argument to `index_in_slice`
function and the function returns indices in the requested order, which
we can then use to set the view.

0.4.19rc4

23 Jan 13:01
7ab620a
Compare
Choose a tag to compare
0.4.19rc4 Pre-release
Pre-release
v0.4.19rc4

fix drawing logic

0.4.19rc3

21 Dec 17:58
5910329
Compare
Choose a tag to compare
0.4.19rc3 Pre-release
Pre-release
Update performance and reduce memory usage for big Labels layer in di…

…rect color mode (#6439)

Closes #6518
Closes #6084

In this PR, similarly to #6411, instead of using `float32` to pass data
to the GPU there we introduce heuristics for choosing smaller data
types, while keeping high performance.

Instead of complex calculation of color in the shader, a precomputed
texture array is used.
To avoid repetitive texture calculation, the textures are cached in the
`Colormap` objects.

For data of type uint8/int8/uint16/int16 we do not perform any transform
of data. We send them to the GPU as it is. This allows to reduce
computational time.

Based on experiments, the rendering performance is a little worse for
uint16/int16 than for uint8/int8. But it may depend on the GPU. Also,
using uint16/int16 means usage more GPU memory than for 8 bits type.
Still less than current main.

For datatypes using at least 32 bits, we add a preprocessing step where
we identify a set of labels that are mapped to the same color and map
all of them to the same value.
This often saves enough space to fall back to uint8/uint16. It allows
using a smaller additional array, and use less GPU memory. If there are
more than `2**16` distinct colors, then float32 is used, though
performance will be reduced.

We support only up to `2**23` distinct colors for now.

For reduced memory usage, part of the functions used for data
preprocessing are compiled using numba. We provide a version of the
function that does not require `numba` but it limits the number of
distinct colors to `2**16` and involves additional array creation (more
memory usage).

---------

Co-authored-by: Juan Nunez-Iglesias <jni@fastmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Lorenzo Gaifas <brisvag@gmail.com>
Co-authored-by: Andy Sweet <andrew.d.sweet@gmail.com>

0.4.19rc2

27 Oct 19:28
11298b0
Compare
Choose a tag to compare
0.4.19rc2 Pre-release
Pre-release
v0.4.19rc2

Separate concurency group for 0.4.19, fix pre-commit

0.4.19rc1

24 Oct 08:48
8860f50
Compare
Choose a tag to compare
0.4.19rc1 Pre-release
Pre-release
Exclude the loaded property when linking two layers (#6377)

Closes #6372

This fixes a bug when linking layers and using the experimental async
loading/slicing feature. The bug exists for both the old implementation
available in v0.4.* and the new implementation available on the main
branch, which are the only things that can cause `Layer.loaded` to
change value and therefore cause the corresponding `Layer.events.loaded`
to be emitted. The underlying cause is that the `loaded` property (which
returns `True` when a layer's slice/view is fully loaded) is read-only
from the public API (i.e. there is no public property setter).

The fix is to add `loaded` to the attribute/property names excluded when
finding the common evented attributes. Even if this were user-settable
(which it should *not* be), it should still be excluded because it
corresponds to a slice/view of a layer which is not state that should be
shared between two linked layers.

I added a test to cover this specific case.

I also fixed some nearby typos.