【问题标题】:Using colorbar with secondary y axis使用带有辅助 y 轴的颜色条
【发布时间】:2026-01-25 09:40:01
【问题描述】:

我正在尝试将颜色条添加到具有辅助 y 轴的图表中。下面给出了我的困难的一个最小的例子。问题是我无法将颜色条添加到 AxesSubplot 对象,并直接将其添加为 plt.colorbar 将其放在我的图形顶部 - 看看它如何与最右边的 y 轴重叠。我怎样才能解决这个问题?干杯。

import matplotlib.pyplot as plt
import numpy as np
import scipy.interpolate

time=[]
temp=[]
temp_f=[]
height=[]
for ti in np.arange( 0, 10, 0.5 ):
    for te in np.arange( -12, 12, 0.5 ):
        height.append( np.sqrt(1+ti)/(1+te*te)+ti*te/12.5 )
        time.append(ti)
        temp.append(te)
        temp_f.append( 32+9.0*te/5)

time=np.array(time)
temp=np.array(temp)
temp_f=np.array(temp_f)
height=np.array(height)

xi, yi = np.linspace(time.min(), time.max(),25), np.linspace(temp.min(), temp.max(), 25)
xi, yi = np.meshgrid(xi, yi)

rbf = scipy.interpolate.Rbf(time, temp, height, function='linear')
zi = rbf(xi, yi)

fig = plt.figure()
ax1 = plt.gca()
ax1.set_xlabel( "Time (s)" )
ax1.set_ylabel( "Celsius" )

ax2 = ax1.twinx()
ax2.set_ylabel( "Fahrenheit" )
ax2.set_ylim( [temp_f.min(), temp_f.max()] )

img = ax1.imshow( zi, vmin=height.min(), vmax=height.max(), origin='lower', 
       extent=[time.min(), time.max(), temp.min(), temp.max()],
       aspect='auto', cmap='YlOrRd')

plt.colorbar(img, label=r"Height (cm)",format='%1.1f', ax=ax1)

plt.show()

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    positioning the colorbar

    您可以通过以下方式手动指定颜色条的位置:

    cbaxes = fig.add_axes([1, 0.15, 0.03, 0.7])
    plt.colorbar(img, label=r"Height (cm)",format='%1.1f', ax=ax1, cax=cbaxes)
    

    【讨论】:

    • 工作就像一个魅力。谢谢!
    【解决方案2】:

    plt.colorbar 可以很好地处理带有一个轴的简单绘图。对于更复杂的设置,它可能会感到困惑。所以最好手动设置颜色条的轴。您可以为此使用subplots 函数。通过提供gridspec_kw,您可以告诉底层GridSpec 对象您希望如何指定宽度:

    fig, [ax1, cax] = plt.subplots(1,2, gridspec_kw=dict(width_ratios=[10,1]))
    

    在创建颜色条时,您要指定用于在以下位置创建颜色条的轴:

    plt.colorbar(img, label=r"Height (cm)",format='%1.1f', ax=ax1, cax=cax)
    

    完整的代码:

    import matplotlib.pyplot as plt
    import numpy as np
    import scipy.interpolate
    
    time=[]
    temp=[]
    temp_f=[]
    height=[]
    for ti in np.arange( 0, 10, 0.5 ):
        for te in np.arange( -12, 12, 0.5 ):
            height.append( np.sqrt(1+ti)/(1+te*te)+ti*te/12.5 )
            time.append(ti)
            temp.append(te)
            temp_f.append( 32+9.0*te/5)
    
    time=np.array(time)
    temp=np.array(temp)
    temp_f=np.array(temp_f)
    height=np.array(height)
    
    xi, yi = np.linspace(time.min(), time.max(),25), np.linspace(temp.min(), temp.max(), 25)
    xi, yi = np.meshgrid(xi, yi)
    
    rbf = scipy.interpolate.Rbf(time, temp, height, function='linear')
    zi = rbf(xi, yi)
    
    fig, [ax1, cax] = plt.subplots(1,2, gridspec_kw=dict(width_ratios=[10,1]))
    ax1.set_xlabel( "Time (s)" )
    ax1.set_ylabel( "Celsius" )
    
    ax2 = ax1.twinx()
    ax2.set_ylabel( "Fahrenheit" )
    ax2.set_ylim( [temp_f.min(), temp_f.max()] )
    
    img = ax1.imshow( zi, vmin=height.min(), vmax=height.max(), origin='lower', 
           extent=[time.min(), time.max(), temp.min(), temp.max()],
           aspect='auto', cmap='YlOrRd')
    
    plt.colorbar(img, label=r"Height (cm)",format='%1.1f', ax=ax1, cax=cax)
    
    plt.show()
    

    你得到:

    【讨论】:

    • 另一个很好的建议。我只想补充一点,如果你想在轴和颜色条之间有更多空间,我可以做 fig, [ax1, dummy, cax] = plt.subplots(1,2, gridspec_kw=dict(width_ratios=[10,1, 1])) 和 dummy.axis('off') 以获得更多空白空间。
    • 实际上,有一种正确的方法可以做到这一点(无需添加未使用的轴):使用 wspace 参数:[ax1, cax] = plt.subplots(1,2, gridspec_kw=dict(width_ratios=[10,1], wspace=0.1))
    • 另请注意,使用已接受答案中的方法,您可以完全控制颜色条的大小和位置。这也意味着高度(和垂直定位)​​不会自动匹配ax1 之一,但也需要手动调整。