I am plotting using the contourf
function from matplotlib
and would like to add a colorbar, I've noticed that sometimes the ticks don't go the max/min values.
Is there a clean way to force it to set ticks at these values?
Note: Checking the max
and min
of z
shows that the colorbar represents values from approx -1 to 1, therefor I would expect this ot be reflected such that one can see the range from the colobar, in addition to some ticks in between.
Plot and code demonstrating what I am talking about:
import matplotlib.pyplot as plt
import numpy as np
# Data to plot.
x, y = np.meshgrid(np.arange(7), np.arange(10))
z = np.sin(0.5 * x) * np.cos(0.52 * y)
fig, ax = plt.subplots()
cs = ax.contourf(x, y, z, levels=25)
ax.grid(c="k", ls="-", alpha=0.3)
fig.colorbar(cs, ax=ax)
fig.savefig("example.png", bbox_inches="tight")
The cleanest way seems to be to give explicit levels to contourf
. If no explicit levels are given, contourf
seems to choose its own, depending on the minimum and maximum value in the data, and also tries to find "nice looking" numbers. After that, ticks get set to a subset of these numbers, such that a tick always coincides with a real level. (If you use colorbar(..., ticks=...)
those ticks will not necessarily coincide with the levels.)
As the sine and cosine don't reach -1
and 1
exact in the given example, they are not part of the range.
The following code shows how the ticks depend on the chosen levels. With np.linspace(-1, 1, 24)
the levels aren't nice round numbers, but matplotlib still chooses a subset to show.
import matplotlib.pyplot as plt
import numpy as np
x, y = np.meshgrid(np.arange(7), np.arange(10))
z = np.sin(0.5 * x) * np.cos(0.52 * y)
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(12, 3))
for ax in (ax1, ax2):
numcontours = 25 if ax == ax1 else 24
cs = ax.contourf(x, y, z, levels=np.linspace(-1, 1, numcontours))
ax.grid(c="k", ls="-", alpha=0.3)
fig.colorbar(cs, ax=ax)
ax.set_title(f'{numcontours} levels from -1 to 1')
plt.show()