Home > Back-end >  What do cmap, vmin, vmax do internally (matplotlib)?
What do cmap, vmin, vmax do internally (matplotlib)?

Time:09-24

Let us say I display an image using matplotlib's imshow as follows:

plt.imshow(IMG, cmap = 'hot', vmin = 0.20, vmax = 0.90)

where IMG is a 2d grayscale image with dtype as float64 and data values in range [0,1].

What is cmap, vmin,vmax doing to the 2d matrix IMG internally that I get a proper output? I wish to understand it properly so that I can replicate its effects on my image and give it as an input to a function for further processing, instead of simply displaying it using plt.imshow(). Any explanation (with or without code demonstration, images) would be appreciated.

CodePudding user response:

A colormap in Matplotlib defines the colors, but always on a normalized scale between 0 and 1 (or 0-255). The vmin and vmax keywords are used to normalize the data you provide, so it is between 0 and 1, and can therefore be mapped according to the colormap.

Those vmin and vmax keywords are basically a shortcut for a linear normalization, which is very common. But other types can also be used, like logarithmic.

Using:

vmin = 0.2
vmax = 0.9
ax.imshow(data, cmap="hot", vmin=vmin, vmax=vmax)

Is short for:

norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax)
ax.imshow(data, cmap="hot", norm=norm)

But using a norm explicitly allows for other types of normalization.

It's fairly easy to do this conversion yourself, which might give a better understanding.

You can get a colormap object using.

import matplotlib.pyplot as plt
import numpy as np

cmap = plt.cm.get_cmap("hot")

enter image description here

The normalization of some sample data can be done with:

data = np.random.rand(20,20)

vmin = 0.2
vmax = 0.9

data_norm = (data - vmin) / (vmax - vmin)

The colormap object can be called with a value, if that value is a float it assumes the range of the colormap is between 0-1. If the value is an integer it assumes it's between 0-255.

For example, the first and last colors of this hot colormap are:

cmap(0.)
# results in: (0.0416, 0.0, 0.0, 1.0) # = almost black

cmap(1.)
# results in: (1.0, 1.0, 1.0, 1.0) # = white

It returns a RGBA tuple, denoting the color for that specific value.

What's nice is that you can also call the colormap with an array of values, so using the normalized data will return an array of those values. This will add an extra dimension at the end of the array, so it changes from 2D to 3D.

That array of colors can be plotted with Matplotlib without any extra information. And that's more or less what Matplotlib does in the background when you specify the cmap,vmin,vmax keywords.

An example tying it all together:

data = np.random.rand(20,20)

vmin = 0.2
vmax = 0.9

data_norm = (data - vmin) / (vmax - vmin)

cmap = plt.cm.get_cmap("hot")
data_rgb = cmap(data_norm)

fig, axs = plt.subplots(
    1, 3, figsize=(6, 2), facecolor="w", 
    subplot_kw=dict(xticks=[], yticks=[]),
)

axs[0].set_title("Default")
axs[0].imshow(data)

axs[1].set_title("Hot   vmin/vmax")
axs[1].imshow(data, cmap="hot", vmin=vmin, vmax=vmax)

axs[2].set_title("Manual RGB")
axs[2].imshow(data_rgb)

enter image description here

  • Related