Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Napari colormaps within OME-Zarr Metadata #29

Open
camFoltz opened this issue Jan 6, 2022 · 4 comments
Open

Napari colormaps within OME-Zarr Metadata #29

camFoltz opened this issue Jan 6, 2022 · 4 comments

Comments

@camFoltz
Copy link

camFoltz commented Jan 6, 2022

I am noticing that the OME-Zarr specifications have an option to have a "color" properties within the channel metadata. We use this property do define the colormap for when napari-ome-zarr opens up the dataset. However, it seems that doing this creates a ton of new colormaps within Napari with the title unnamed, and doesn't actually use a napari colormap.

Is there a way to define metadata such that we use napari's inherent colormaps? I see that the _reader.py looks for a metadata key called colormap which gets converted to a vispy colormap, but I am not entirely sure how to include this in the ome metadata within the zarr file or if this vispy colormap will correspond to one of napari's inherent maps and not create a new 'unnamed' one.

Let me know if I can clarify anything here. Thanks for the help

@aeisenbarth
Copy link

I have the same issue. We load many OME-Zarr files which specify a channel's color like cm = [[0, 0, 0], [1.0, 0.0, 0.0]]. For each of them, a new Vispy Colormap instance is created. Since they are unnamed, Napari treated all of them as separate, unique color maps.

A first, obvious fix was to give the colormap a name (name=str(cm)), but Vispy's colormaps have no name attribute.

After importing Napari's Colormap which has a name attribute, Napari matches all the Colormap instances by name and displays a single one in the user interface. Still, this is not the right approach: The UI only displays a single colormap because of key collision, but layers keep their separate Colormap instances (with same names).

We would need to lookup whether there already exists a suitable colormap instance (like from Napari's AVAILABLE_COLORMAPS) and re-use it or create a new one and register it.

@will-moore
Copy link
Member

It could be possible to compare color values coming from OME-NGFF metadata with those in existing napari colormaps and if there's a match, then use the napari colormap name instead:
https://napari.org/stable/howtos/layers/image.html#working-with-colormaps
It might also be permissible to use the name of the colormap in the omero channel color string (as we do in OMERO itself for lookup tables).

@aeisenbarth
Copy link

When we first look up existing colormap instances, we can avoid creating new identical ones.

If the OME-Zarr colormap is a name (string), one can try to look it up from Napari colormaps (how to handle it if not found?). If it is instead a tuple of two RGB colors, create a new Napari colormap. Since Napari will register it, we can look it up next time.

from vispy.color import Colormap as VispyColormap
from napari.utils.colormaps.colormap import Colormap as NapariColormap
from napari.utils.colormaps import AVAILABLE_COLORMAPS

cms = metadata.get("colormap", [])
for idx, cm in enumerate(cms):
    if not isinstance(cm, (VispyColormap, NapariColormap)):
        if isinstance(cm, str):
            cms[idx] = AVAILABLE_COLORMAPS.get(cm)
            # TODO: How to handle this?  We have a colormap name not know in Napari,
            # are there cases when we can still create a color map?
        else:
            colormap_name = f"color {cm}"
            colormap = AVAILABLE_COLORMAPS.get(colormap_name)
            if colormap is None:
                colormap = NapariColormap(cm, name=colormap_name)
            cms[idx] = colormap

@mezwick
Copy link

mezwick commented Aug 15, 2024

Hi.

I've come across this issue myself and wasn't clear if there is a fix, or if this issue is due to me writing metadata incorrectly. Was hoping you could help.

I have written my high plex multichannel data to OME-ZARR format with ome-zarr-py package write_image function. I specify channel metadata under OMERO metadata, including each channel color to be "FFFFFF".

On loading to napari via napari-ome-zarr, channel names and render settings load correctly. But each channel spawns its own version of 'unnamed colormap [##]'

image

Looking for a way to have every channel just load with the napari 'gray' colormap?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants