I want to make a plot using imshow(), but with a little custom colormap. For positive values I want to use e.q. "gnuplot" colors and for neagtive "cool". Any idea how to do this?
Asked
Active
Viewed 1,358 times
2
-
1Your problem looks similar to http://stackoverflow.com/questions/24997926/making-a-custom-colormap-using-matplotlib-in-python – Scott May 06 '15 at 16:33
-
also see http://stackoverflow.com/questions/16834861/create-own-colormap-using-matplotlib-and-plot-color-scale -- note registering the colormap, which is maybe only mentioned in the comments. – cphlewis May 06 '15 at 17:07
1 Answers
3
You could use
cmap, norm = mcolors.from_levels_and_colors(levels, colors)
to construct a custom colormap.
For example,
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
data = np.linspace(-10,5,20).reshape(5,4)
cmap = {name:plt.get_cmap(name) for name in ('gnuplot', 'cool')}
N = 50
vmin, vmax = (np.nextafter(min(data.min(), -1), -np.inf),
np.nextafter(max(data.max(), 1), np.inf)) # 1
levels = np.concatenate([np.linspace(vmin, 0, N, endpoint=False),
np.linspace(0, vmax, N+1, endpoint=True)]) # 2
colors = np.concatenate([cmap[name](np.linspace(0, 1, N))
for name in ('cool', 'gnuplot')]) # 3
cmap, norm = mcolors.from_levels_and_colors(levels, colors)
plt.imshow(data, cmap=cmap,
norm=norm,
interpolation='nearest')
bar = plt.colorbar()
plt.show()
yields

I wish the definition of
vmin, vmaxcould be simpler.min(data.min(), -1)is used instead ofdata.min()in casedatais positive. We needvminto be negative for the custom colormap to be properly constructed. Thenp.nextafternudgesvmindown a little bit so the levels will encapsulate all the values indata. Withoutnp.nextafter,imshowhas a big white block whendataequalsvmax.The colorbar levels go from
vminto0(exclusive), then0(inclusive) tovmax.The colorbar colors are a concatenation of
Ncolors sampled fromcool, followed byNcolors sampled fromgnuplot. You can changeNto control how many gradations of color from each underlying colormap you wish to have.
unutbu
- 842,883
- 184
- 1,785
- 1,677