I want to make a contour plot, with a specific contour line using matplotlib, the important piece of code is the following:
levels = [-5, -3,-2,-1, 0,1, 2,5,10,17.5]
cax = ax1.contourf(X,Y,Z,levels)
#some similar code
In the end, is scale of the contour plot is the on the following picture, however, I don't like that the contour between (-5,0) becomes only variants of dark blue and purple, How can I make the colour scale more varied, without needing to change the scale?
There are several things that could help you
cm.PRGrn
)ax.contour(...)
to draw contour lines across the boundaries of different levelsax.contourf(...)
at all, but a combination of ax.imshow(...)
and ax.contour(...)
, as it's shown in the right subplot; note the differences in the two colorbars.This is the code used to produce the figure at the top.
Matplotlib's example recommends using the exact levels
that are recomputed in the filled contour object; note also extend='both'
in ax.contourf
's parameters.
The code for ax.imshow
is relatively straightforward, note the use of extent
to have correct axis limits, origin='lower'
to have the y axis going upwards, and the (optional) use of TwoSlopeNorm
to have the colormap centered about zero and extending to the data extremes.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.cm import PRGn
from matplotlib.colors import TwoSlopeNorm
x = y = np.linspace(-2, 2, 81)
X, Y = np.meshgrid(x, y)
Z = 5*X + 4*Y + 4 - 2
levels = [-5, -3, -2, -1, 0, 1, 2, 5, 10, 17.5]
extent = (-2, 2, -2, 2)
fig, (ax0, ax1) = plt.subplots(1, 2, figsize=(10, 4), layout='constrained')
cf0 = ax0.contourf(X, Y, Z, levels=levels, cmap=PRGn, extend='both')
cc0 = ax0.contour( X, Y, Z, levels=cf0.levels, colors='k')
cl0 = ax0.clabel(cc0)
cb0 = fig.colorbar(cf0, ax=ax0)
ax0.set_aspect(1)
im1 = ax1.imshow(Z, extent=extent, origin='lower', cmap=PRGn, norm=TwoSlopeNorm(0))
cc1 = ax1.contour(Z, levels, colors='k', origin='lower', extent=extent)
cl1 = ax1.clabel(cc1)
cb1 = fig.colorbar(im1, ax=ax1)
plt.show()