在使用 Matplotlib 绘制多个子图时,我们常常希望子图的横坐标保持一致。可以通过获取第一个子图的 x 轴范围 (xlim),并将其传递给后续子图来实现。然而,有时在传递过程中,xlim 无法正确应用于后续子图,导致横坐标不一致。

问题描述

在以下代码示例中,我们尝试获取第一个子图的 xlim,并将其传递给第二个子图:

xlim=ax.get_xlim()#取上一个子图的xlim

def plotDigitalChannel(ax,start,end,datalist,labellist,tick=1000,xlim=(0.1,0.9)):
    
    num=len(datalist)
    if num+2!=len(labellist):
        return ax
    

    colorlist=allcolorlist[:num]
    hexcolorlist=allhexcolorlist[:num]
    for i in range(0,num):
        xranges = xranges_broken_barh(datalist[i],start)  
        if len(xranges)>0:
            PolyCollection=ax.broken_barh(xranges,(0.9+i, 0.2),color=colorlist[i])
            Line2D=ax.axhline(y=i+1, color=colorlist[i], linestyle='-',linewidth=1)
        else:
            Line2D=ax.axhline(y=i+1, color=colorlist[i], linestyle='-',linewidth=1)
    yliminfo=ax.set_ylim(0, num+1)
    xliminfo=ax.set_xlim(xlim)#用参数设置xlim,可以看到xliminfo返回值正确,但实际不起效果,为何?
    y_pos=np.arange(num+2)
    ax.set_yticks(y_pos)#, labels=''
    ax.set_yticklabels(labels=labellist)
    labels=ax.get_yticklabels()
    for i in range(0,num):        
        labels[i+1].set_color(colorlist[i])   
    ax.invert_yaxis() 
   
    sec_formatter = ticker.FuncFormatter(lambda x, pos: format_sec(x, tick)) # 增加一个lambda函数,将tick作为参数传递给format_sec函数
    ax.xaxis.set_major_formatter(sec_formatter)
    ax.grid(linestyle='--') 
    ax.tick_params(left = False,bottom = False)  
    
    return ax

尽管 xlim 返回值正确,但在设置第二个子图的 xlim 时,实际效果却与预期不符。

解决方案

问题的原因可能是因为在设置第二个子图的 xlim 时,已经超出了第一个子图的范围,导致传递的 xlim 无效。解决方法是在设置第二个子图的 xlim 时,以第一个子图的 xlim 为参考,进行调整。

修改后的代码

def plotDigitalChannel(ax,start,end,datalist,labellist,tick=1000,xlim=(0.1,0.9)):
    
    num=len(datalist)
    if num+2!=len(labellist):
        return ax

    colorlist=allcolorlist[:num]
    hexcolorlist=allhexcolorlist[:num]
    for i in range(0,num):
        xranges = xranges_broken_barh(datalist[i],start)  
        if len(xranges)>0:
            PolyCollection=ax.broken_barh(xranges,(0.9+i, 0.2),color=colorlist[i])
            Line2D=ax.axhline(y=i+1, color=colorlist[i], linestyle='-',linewidth=1)
        else:
            Line2D=ax.axhline(y=i+1, color=colorlist[i], linestyle='-',linewidth=1)
    yliminfo=ax.set_ylim(0, num+1)
    xliminfo=ax.set_xlim(xlim)
    y_pos=np.arange(num+2)
    ax.set_yticks(y_pos)
    ax.set_yticklabels(labels=labellist)
    labels=ax.get_yticklabels()
    for i in range(0,num):        
        labels[i+1].set_color(colorlist[i])   
    ax.invert_yaxis() 
   
    sec_formatter = ticker.FuncFormatter(lambda x, pos: format_sec(x, tick))
    ax.xaxis.set_major_formatter(sec_formatter)
    ax.grid(linestyle='--') 
    ax.tick_params(left = False,bottom = False)  
    
    return ax

fig, (ax1, ax2) = plt.subplots(nrows=2, ncols=1, sharex=True, figsize=(10,6))
# 第一个子图
ax1.plot(x1, y1)
ax1.set_title('First Subplot')
# 第二个子图
ax2.plot(x2, y2)
ax2.set_title('Second Subplot')
# 取第一个子图的xlim,并传递给第二个子图
xlim = ax1.get_xlim()
ax2.set_xlim(xlim)

plt.show()

通过使用 sharex=True 参数创建子图,并使用 ax2.set_xlim(xlim) 传递 xlim,可以确保子图的横坐标保持一致。

总结

本文介绍了 Matplotlib 子图横坐标一致性问题,并提供了解决传递失效问题的代码示例。希望本文能够帮助读者在使用 Matplotlib 绘制多个子图时,轻松实现横坐标一致性。


原文地址: https://www.cveoy.top/t/topic/jYAT 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录