LinearSegmentedColormap, Normalize, and colorbar

Hello,

I'm trying to teach myself to create custom colormaps to highlight
certain aspects of a dataset I am working with. The script below
produces two plots -- the first shows a 4x4 array foo of random floats
between 0.0 and 1.0, and the second shows the same array, but normalized
such that [foo.min(), foo.max()] is mapped to [0.0, 1.0].

As I understand it, I am plotting two slightly different datasets using
the same colormap, yet the two colorbars are different -- note the
value at the transition from grayscale to red.

I am not sure whether the colors are being assigned to slightly
different data values in the two plots, or if the problem is in plotting
the colorbar. I'd appreciate any help!

Thanks,
Tim

···

--

Timothy W. Hilton
PhD Candidate, Department of Meteorology
The Pennsylvania State University
503 Walker Building, University Park, PA 16802
hilton@...3085...

=========

import numpy as np
import numpy.ma as ma
import matplotlib.pyplot as plt
import matplotlib as mpl

mycmdata1 = {'red': ((0.0, 0.0, 0.0),
                     (0.5, 1.0, 0.7),
                     (1.0, 1.0, 1.0)),
             'green': ((0.0, 0.0, 0.0),
                       (0.5, 1.0, 0.0),
                       (1.0, 1.0, 1.0)),
             'blue': ((0.0, 0.0, 0.0),
                      (0.5, 1.0, 0.0),
                      (1.0, 0.5, 1.0))}
mycm1 = mpl.colors.LinearSegmentedColormap('mycm1', mycmdata1)

N = 4
np.random.seed(0)
foo = np.random.rand(N, N)

plt.figure()
plt.pcolor(foo, cmap=mycm1)
plt.colorbar()

plt.figure()
norm = mpl.colors.Normalize()
plt.pcolor(norm(foo), cmap=mycm1)
plt.colorbar()

Hello Tim,

Nice to see more students at PSU meteo jumping in on matplotlib (I am a graduate from there).

When you call pcolor() without specifying the vmin and the vmax values, pcolor() will automatically normalize your input data to the range of 0.0 to 1.0 for the purposes of coloring, but the ticks on the colorbar will be based on the original input values. When you normalized the data yourself, the colorbar for that plot will use the given input values for deciding the tick values, since it could not know what the original data had.

Note that both pcolors are producing identically colored plots, it is just the colorbar that shows a different color<->value relationship. Now, to illustrate this point further, let’s pick a colormap that changes rapidly, such as ‘flag’. Change the line:

mycm1 = mpl.colors.LinearSegmentedColormap(‘mycm1’, mycmdata1)

to

mycm1 = ‘flag’

And then run the script. You will see the plots are still identical. Now, change the first pcolor call from

plt.pcolor(foo, cmap=mycm1)

to

plt.pcolor(foo, cmap=mycm1, vmin=0.0, vmax=1.0)

and run the script. The plots are different! But the colorbars are the same! This is because the data going into the two pcolors calls are different and so all of this behavior is as expected.

I hope this clears things up for you, and I hope you continue to enjoy using matplotlib!

Ben Root

P.S. - Tell Dr. Young I said “Hi!”

···

On Wed, Dec 8, 2010 at 9:15 PM, Timothy W. Hilton <hilton@…3361…> wrote:

Hello,

I’m trying to teach myself to create custom colormaps to highlight

certain aspects of a dataset I am working with. The script below

produces two plots – the first shows a 4x4 array foo of random floats

between 0.0 and 1.0, and the second shows the same array, but normalized

such that [foo.min(), foo.max()] is mapped to [0.0, 1.0].

As I understand it, I am plotting two slightly different datasets using

the same colormap, yet the two colorbars are different – note the

value at the transition from grayscale to red.

I am not sure whether the colors are being assigned to slightly

different data values in the two plots, or if the problem is in plotting

the colorbar. I’d appreciate any help!

Thanks,

Tim