My code:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
fig, ax = plt.subplots()
contour_levels = [10,100,500,1000,10000]
h = np.histogram2d(np.random.normal(0,2,10000),np.random.normal(0,2,10000),bins=10)
c = ax.contourf(h[0].T,cmap='magma',norm=LogNorm(),levels=contour_levels,extend='both')
cbar = plt.colorbar(c)
ticks = cbar.ax.yaxis.get_ticklabels()
cbar.ax.tick_params(which='minor',size=8,width=1,colors='white')
cbar.ax.tick_params(which='major',size=15,width=1,colors='white')
[t.set_color('black') for t in ticks]
ax.set_aspect('equal')
plt.show()
The result:
>print(ticks)
[Text(1, 10.0, '$\\mathdefault{10^{1}}$'),
Text(1, 56.234132519034915, '$\\mathdefault{10^{2}}$'),
Text(1, 316.2277660168379, ''),
Text(1, 1778.2794100389228, '$\\mathdefault{10^{3}}$'),
Text(1, 10000.0, '$\\mathdefault{10^{4}}$')]
Issue:
Quite alarmingly, the colorbar tick labels only match the corresponding tick value on the first and last ticks! The bizarre locations of the minor ticks hinted at the major tick labels being wrongly placed (except for the minor ticks leading to 10^4).
Any idea of what is going on? Thank you in advance!
CodePudding user response:
By default, the colorbar ticks for a contour plot are distributed uniformly (same distance for each color). You can change this to spacing='proportional'
to have each color use its corresponding proportion of the colorbar.
(With color='white'
instead of colors=...
in the tick_params
, only the colors of the ticks themselves are changed, not the tick labels.)
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
import numpy as np
fig, ax = plt.subplots()
contour_levels = [10, 100, 500, 1000, 10000]
h, xedges, yedges = np.histogram2d(np.random.normal(0, 2, 10000), np.random.normal(0, 2, 10000), bins=10)
h[h == 0] = np.nan
cont = ax.contourf((xedges[:-1] xedges[1:]) / 2, (yedges[:-1] yedges[1:]) / 2, h.T, cmap='magma', norm=LogNorm(),
levels=contour_levels, extend='both')
cbar = plt.colorbar(cont, ticks=contour_levels, format='%.0f', spacing='proportional')
ticks = cbar.ax.yaxis.get_ticklabels()
cbar.ax.tick_params(which='minor', size=8, width=1, color='white', direction='in')
cbar.ax.tick_params(which='major', size=15, width=1, color='white', direction='in')
ax.set_aspect('equal')
plt.show()