I recently started working with colorbars. I had a colorbar that looked like this:
Now I'd like to change all the values $x$ next to it, to $10^x$, but keep the new values at the original location of $x$. I tried to do that by using : cbar.set_ticks([10**t for t in cbar.ax.get_yticks()])
Now the colorbar code part looks like this:
kaart = ax.contourf(lons, lats, np.log10(Ui),cmap=plt.cm.BuGn, transform = ccrs.PlateCarree())
cbar =plt.colorbar(kaart)
cbar.set_label( label='Uncertainty in celcius', size = 20)
cbar.set_ticks([10**t for t in cbar.ax.get_yticks()])
But the resulting colorbar looks like :
How can I keep the labels at their original place? Thanks in advance :)
One solution is to set a tick formatter that given the exponent creates a label of the desired form.
A better solution is to use locator=LogLocator()
in the call to contourf()
. With the LogLocator
you can specify for which multiples of 10 you want a subdivision. Default subs=(1,)
: only at the exact powers of 10. Changing this to subs=(1,2,)
would use powers of 10 and twice powers of 10.
import matplotlib.pyplot as plt
from matplotlib.ticker import LogLocator, LogFormatterMathtext
import numpy as np
lons = np.linspace(0, 50, 20)
lats = np.linspace(0, 40, 10)
Ui = np.power(10, np.random.uniform(-2.8, 0.4, size=(10, 20)))
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(16, 5))
kaart1 = ax1.contourf(lons, lats, np.log10(Ui), cmap='BuGn')
cbar1 = plt.colorbar(kaart1, ax=ax1)
cbar1.ax.yaxis.set_major_formatter(lambda x, pos: f'$10^{{{x:.1f}}}$')
ax1.set_title('Special purpose tick formatter')
kaart2 = ax2.contourf(lons, lats, Ui, locator=LogLocator(), cmap='BuGn')
cbar2 = plt.colorbar(kaart2, ax=ax2)
ax2.set_title('Default LogLocator')
kaart3 = ax3.contourf(lons, lats, Ui, locator=LogLocator(subs=(1, 2)), cmap='BuGn')
cbar3 = plt.colorbar(kaart3, ax=ax3)
cbar3.ax.yaxis.set_major_formatter(LogFormatterMathtext())
ax3.set_title('LogLocator(subs=(1, 2))')
plt.tight_layout()
plt.show()