【问题标题】:Draw colorbar with twin scales用双刻度绘制颜色条
【发布时间】:2026-01-05 23:50:01
【问题描述】:

我想绘制一个(垂直)颜色条,它的每一侧都有两个不同的比例(对应于相同数量的两个不同单位)。一方面考虑华氏度,另一方面考虑摄氏度。显然,我需要单独指定每一边的刻度。

知道我该怎么做吗?

【问题讨论】:

  • matplotlib.org/examples/api/two_scales.html,你试过了吗,发个示例数据
  • 我正在用pcolormesh 绘制二维数据。我的问题是关于颜色条,而不是关于轴本身。
  • 能否提供样本数据
  • @andreas-h Colorbars 存在于 Axes 上(您可以使用 ax 属性访问它),因此您应该能够像使用更大的绘图 Axes 一样使用比例尺。

标签: matplotlib colorbar


【解决方案1】:

这应该让你开始:

import matplotlib.pyplot as plt
import numpy as np

# generate random data
x = np.random.randint(0,200,(10,10))
plt.pcolormesh(x)

# create the colorbar
# the aspect of the colorbar is set to 'equal', we have to set it to 'auto',
# otherwise twinx() will do weird stuff.
cbar = plt.colorbar()
pos = cbar.ax.get_position()
cbar.ax.set_aspect('auto')

# create a second axes instance and set the limits you need
ax2 = cbar.ax.twinx()
ax2.set_ylim([-2,1])

# resize the colorbar (otherwise it overlays the plot)
pos.x0 +=0.05
cbar.ax.set_position(pos)
ax2.set_position(pos)

plt.show()

【讨论】:

  • 您不需要调整颜色条的大小,只需将axisbelow设置为False: cbar.ax.set_axisbelow(False) # 1.axis ax2 = cbar.ax.twinx() ax2.set_ylim([ low,high]) # 限制的低高 ax2.set_axisbelow(False) # 2.axis
  • @Andreas 我不明白你的意思:set_axisbelow 对坐标区实例的大小或位置没有影响。
  • 啊,我明白你的意思了,我以为是为了抵消 2. 轴 - 所以在你的上下文中忽略这个,抱歉造成混淆
【解决方案2】:

如果为颜色条创建子图,则可以为该子图创建一个双坐标轴,并像普通坐标轴一样对其进行操作。

import matplotlib.colors as mcolors
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-1,2.7)
X,Y = np.meshgrid(x,x)
Z = np.exp(-X**2-Y**2)*.9+0.1

fig, (ax, cax) = plt.subplots(ncols=2, gridspec_kw={"width_ratios":[15,1]})

im =ax.imshow(Z, vmin=0.1, vmax=1)
cbar = plt.colorbar(im, cax=cax)
cax2 = cax.twinx()

ticks=np.arange(0.1,1.1,0.1)
iticks=1./np.array([10,3,2,1.5,1])
cbar.set_ticks(ticks)
cbar.set_label("z")
cbar.ax.yaxis.set_label_position("left")
cax2.set_ylim(0.1,1)
cax2.set_yticks(iticks)
cax2.set_yticklabels(1./iticks)
cax2.set_ylabel("1/z")

plt.show()

【讨论】:

    【解决方案3】:

    我正在为我的颜色条使用插入轴,出于某种原因,我发现上面的答案从 v3.4.2 开始不再有效。 twinx 占据了整个原始子情节。

    所以我只是复制了插图轴(而不是使用 twinx)并增加了原始插图上的 zorder。

    axkws = dict(zorder=2)
    cax = inset_axes(
        ax, width="100%", height="100%", bbox_to_anchor=bbox, 
        bbox_transform=ax.transAxes, axes_kwargs=axkws
    )
    cbar = self.fig.colorbar(mpl.cm.ScalarMappable(cmap=cmap), cax=cax)
    cbar.ax.yaxis.set_ticks_position('left')
        
    caxx = inset_axes(
        ax, width="100%", height="100%", 
        bbox_to_anchor=bbox, bbox_transform=ax.transAxes
    )
    caxx.yaxis.set_ticks_position('right')
    

    【讨论】: