pythonmatplotlibcontourcolormapcontourf

contour does not plot specified number of contours


I generate some data within a loop and like to plot them as a contour plot. Each plot should use the same colormap and a specified number of contour levels. Also, the first level color should be white.

The figure generated by the following snippet resembles the problem I face at the moment:

import numpy as np
import matplotlib.pyplot as plt

x = y = np.linspace(-3, 3, 200)
data = 1800*np.exp(-(x[newaxis, :].T**2 + y**2))

plt.figure(1000)
plt.clf()

plt.contourf(x, y, data, 8, cmap=plt.cm.OrRd)
plt.axes().set_aspect("equal")
plt.colorbar()
plt.contour(x, y, data, 8, colors='k')

enter image description here

There are 9 and not 8 contour levels which I noticed seems to depend on the min/max values of the data. So the number of contour levels is not identical in the figures I generate within my loop since the data changes. And which colormap can I use so that the first level is white? I know there are gazillions of questions about colormaps out there. But they tend to generate a colormap by hand. I just want to use this existing one and either add white as first color or somehow modify my script so that it does start with white (which I thought it would anyway).


Solution

  • The levels argument in .contourf or .contour, specifies the number of levels. I.e. for a contour plot this is the number of lines you get and for a contourf plot this is one less than the number of differently colored regions. For example if you take a single level, you get one line and two colored regions.

    enter image description here

    To get white as first color you need to choose a colormap that actually has white as first color (Note that OrRd does not have white in it). Looking at the colormap reference, such a map would e.g. be the reversed afmhot. Of course you could also build your custom map which has white as first color. The color of the respective range from the colormap is chosen such that it takes the color from the middle of the interval between levels. This would result in a non-white color even for the first level. To overcome this one may choose to generate a colormap with N+1 colors from the given colormap, such that the color is constant over the interval and the mean is still the same as the starting color.

    levels = 8
    cmap= plt.cm.get_cmap("afmhot_r", levels+1)
    plt.contourf(x, y, data, levels, cmap=cmap)
    

    produces:

    enter image description here