# Display multi-channel images with scikit-image

Hi scikit-image friends,

maybe a stupid beginners question (sorry, googling didn’t help), but is there a straightforward / easy-to-use way for displaying multi-channel images, e.g. in Jupyter notebooks?

For example, this code:

``````from skimage.io import imread, imshow

imshow(image)
``````

Results in this visualization:

In Fiji, it looks like this:

Any hint and/or links to basics tutorials are very welcome!

Thanks and Happy Easter!

Cheers,
Robert

1 Like

the only straightforward way is in the case where you have three channels and are happy with an RGB colourmap. In that case, if you pass a N x M x 3 array of floats between 0 and 1 or of integers between 0 and 255, `imshow` works as you expect. In your case you should normalize your image. For example `imshow(image/image.max())` gives something approaching what you need:

As soon as you want to change things like colormaps, I was surprised some time ago to see that there’s (to my knowledge) no easy package to use for that. I made an example here how to do that “manually”. I’m really interested to know if you or anybody else knows of better solution (just for simple 2D plots like this as napari takes care of more advanced cases but is “heavier” to use)!
Cheers,
Guillaume

2 Likes

@guiwitz Perhaps Matplotlib’s linear segmented colormap will simplify your example. As you show, applying a colormap to an image is typically done using `cmap(gray_values)`.

Hey @guiwitz ,

thanks for the hint! It works like a charm.

Hey @stefanv ,

That sounds very interesting! Not sure if I’m using it the right way, but copy-pasting and extrapolating code from the website you linked leads to this:

``````from skimage.io import imread, imshow

cdict = {'red':   [(0.0,  0.0, 0.0),
(0.5,  1.0, 1.0),
(1.0,  1.0, 1.0)],

'green': [(0.0,  0.0, 0.0),
(0.25, 0.0, 0.0),
(0.75, 1.0, 1.0),
(1.0,  1.0, 1.0)],

'blue':  [(0.0,  0.0, 0.0),
(0.5,  0.0, 0.0),
(1.0,  1.0, 1.0)]}

from matplotlib.colors import LinearSegmentedColormap
cmap = LinearSegmentedColormap("rgb", cdict)

imshow(image, cmap=cmap)
``````

Can you outline how one can make an RGB-color map as in ImageJ?

Thanks to both of you for your time!

Robert

It’s nice to know that with `LinearSegmentedColormap` there’s an alternative to create colormaps but in this specific case I’m not sure it helps a lot. With an NxMx3 array, `imshow` defaults to RGB for normalized data or to viridis if not normalized and I don’t think one can do anything about it. The colormap defined by `LinearSegmentedColormap` in the example defines a map for a single channel. So for example you get this if you just use the last channel:

``````from matplotlib.colors import LinearSegmentedColormap

cdict = {'red':   [(0.0,  0.0, 0.0),
(0.5,  1.0, 1.0),
(1.0,  1.0, 1.0)],

'green': [(0.0,  0.0, 0.0),
(0.25, 0.0, 0.0),
(0.75, 1.0, 1.0),
(1.0,  1.0, 1.0)],

'blue':  [(0.0,  0.0, 0.0),
(0.5,  0.0, 0.0),
(1.0,  1.0, 1.0)]}

cmap = LinearSegmentedColormap("rgb", cdict)

imshow(image[:,:,2], cmap=cmap)
``````

So to my knowledge there’s no way to easily create a multi-channel colormap with a single function. You need to (1) create a colormap for each channel, (2) transform each single channel into an RGB image displaying the colormap defined in (1) and 3) assemble all channels into a single RGB image using your favorite projection.

1 Like

I was wondering if we can take the approach to write a function that generates a LUT like in ImageJ. We could send it as PR to matplotlib or scikit-image…

Yes, that’s a good idea! Since this is primarily about visualization, matplotlib may be the most logical landing place. But we do have some utility functions in scikit-image for computing colorized images as well, such as label2rgb.

1 Like