Instead of using cmap, I will carefully work out my own production.
As you already noticed, in order to have absolute control over colors (without going through an array of colors) when using cmaps, the number of colors in cmap should be equal to the number of levels - 1.
We can easily demonstrate this in the following example. Let's make a color code with three primary colors in:
import matplotlib.pyplot as plt import matplotlib.colors as mcolors import numpy data = numpy.arange(12).reshape(3, 4) cmap = mcolors.ListedColormap([(0, 0, 1), (0, 1, 0), (1, 0, 0)])
However, when we start using with anything other than 3 + 1 levels, we get results that you cannot expect:
plt.subplot(121) plt.contourf(data, cmap=cmap, levels=[1, 4, 8, 10]) plt.subplot(122) plt.contourf(data, cmap=cmap, levels=[1, 4, 8]) plt.show()
So, I showed that your levels should have length n_colors-1
, but since we want to have 3 colors, and the average color is always shown, we also need to have an even number of levels.
Ok, now we have some basic rules, let's create a LinearSegmentedColormap, which is essentially just a ListedColormap interpolated to N colors:
levs = range(12) assert len(levs) % 2 == 0, 'N levels must be even.' cmap = mcolors.LinearSegmentedColormap.from_list(name='red_white_blue', colors =[(0, 0, 1), (1, 1., 1), (1, 0, 0)], N=len(levs)-1, ) plt.contourf(data, cmap=cmap, levels=levs) plt.show()
We can verify that the normal cmap is white as the middle color programmatically:
>>> print cmap(0.5) (1.0, 1.0, 1.0, 1.0)
I hope this will give you all the information you need to be able to make any color map that you like and successfully use it in contouring.