You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib多子图双Y轴对齐问题求助

解决Matplotlib双Y轴副轴刻度对齐问题

我太懂你这个困扰了——用twinx()搞出来的双Y轴副轴,想让它们在多个子图间对齐刻度,直接用get_shared_y_axes().join()确实经常不管用,因为这些副轴是绑定在主图轴上的独立对象,和subplots()生成的原生子图轴共享机制根本不是一套逻辑。

为什么你的原有方法失效?

get_shared_y_axes().join()本来就是给subplots()创建的原生轴设计的,而twinx()生成的副轴属于“寄生”在主轴上的轴,它们的共享逻辑不会自动触发刻度同步,所以哪怕你调用了join方法,副轴刻度该不对齐还是不对齐。

简洁解决方案:自动同步副轴Y范围

完全不用手动去查数据极值,我们可以先收集所有副轴的初始Y数据范围,算出全局的最小和最大值,再统一设置所有副轴的刻度范围,就能实现完美对齐。修改后的代码如下:

import matplotlib.pyplot as plt
import pandas as pd

excel_file = 'test_data.xlsx'
sims = ['Sim 02', 'Sim 01', 'Sim 03']

if __name__ == '__main__':
    # 注意:新版pandas里sheetname已改为sheet_name,skipfooter参数保持不变
    data = pd.read_excel(excel_file, skiprows=[0,1,2,3], sheet_name=None, header=1, index_col=[0,1], skipfooter=10)
    plot_cols = len(sims)
    plot_rows = 2
    f, axes = plt.subplots(plot_rows, plot_cols, sharex='col', sharey='row')
    secondary_ax = []
    secondary_ylims = []  # 用来收集所有副轴的Y刻度范围
    
    for i, sim in enumerate(sims):
        df = data[sim]
        modern = df.loc['Modern']
        
        # 主Y轴绘制Idle数据
        axes[0][i].plot(modern.index, modern['Idle'])
        # 创建副轴并绘制Work数据
        ax2 = axes[0][i].twinx()
        secondary_ax.append(ax2)
        ax2.plot(modern.index, modern['Work'])
        # 记录当前副轴的Y刻度范围
        secondary_ylims.append(ax2.get_ylim())
        
        # 第二行绘制Result柱状图
        axes[1][i].bar(modern.index, modern['Result'])
        axes[0][i].set_xlim(12, 6)
    
    # 计算所有副轴的公共Y范围:取所有最小值里的最小,最大值里的最大
    global_min = min(ylim[0] for ylim in secondary_ylims)
    global_max = max(ylim[1] for ylim in secondary_ylims)
    # 统一设置所有副轴的Y范围
    for ax in secondary_ax:
        ax.set_ylim(global_min, global_max)
    
    plt.show()

可选:动态同步缩放(交互场景)

如果需要在用户缩放副轴时,其他副轴也自动同步刻度,可以加一个事件回调函数:

# 在plt.show()之前添加以下代码
def sync_secondary_axes(event):
    # 以第一个副轴为基准,同步所有其他副轴的刻度范围
    ref_ylim = secondary_ax[0].get_ylim()
    for ax in secondary_ax[1:]:
        ax.set_ylim(ref_ylim)

# 绑定鼠标释放事件(缩放/平移操作完成后触发同步)
f.canvas.mpl_connect('button_release_event', sync_secondary_axes)

这个方案完全不需要手动干预数据,代码简洁还易维护,完美解决副轴刻度对齐的问题。

内容的提问来源于stack exchange,提问作者M Dillon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:29:04