更改值时将颜色条标签保持在旧位置

Keeping colorbar labels at old position when changing their value

我最近开始使用颜色条。我有一个看起来像这样的颜色条:

现在我想将其旁边的所有值 $x$ 更改为 $10^x$,但将新值保留在 $x$ 的原始位置。我试图通过使用来做到这一点:cbar.set_ticks([10**t for t in cbar.ax.get_yticks()])

现在颜色条代码部分如下所示:

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()])

但是生成的颜色条看起来像:

如何将标签保留在原来的位置? 提前致谢:)

您正在更改刻度的值,所以可能:

ticks = cbar.ax.get_yticks()
mylabels = [f'{10**t}' for t in ticks]
cbar.set_ticks(ticks, labels=mylabels)

但是,如果您真的要绘制数据的对数,请考虑 contouring/pcolor 原始数据并使用 LogNorm:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
data = 10**np.random.randn(10, 10)
fig, ax = plt.subplots()
pc = ax.pcolormesh(data, norm=mcolors.LogNorm(vmin=10**-3, vmax=10**3))
fig.colorbar(pc)
plt.show()

一个解决方案是设置一个 tick formatter 给定指数创建所需形式的标签。

更好的解决方案是 use locator=LogLocator() in the call to contourf(). With the LogLocator 您可以指定要细分的 10 的倍数。默认 subs=(1,):仅在 10 的精确次方。将其更改为 subs=(1,2,) 将使用 10 的次方和 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'^{{{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()