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

如何修复Matplotlib 2×2子图y轴刻度不一致问题

统一Matplotlib 2×2子图Y轴刻度的解决方案

我在处理多工作表Excel文件的压缩测试数据时,用Matplotlib绘制了2×2布局的子图,但发现各子图的Y轴刻度不一致,而实际需求是让所有子图的Y轴刻度保持统一。

示例代码如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

fig, axes = plt.subplots(2, 2, constrained_layout=True, 
                        figsize=(7,7),)

height=6
diameter=13
Circle_area=3.14159265359*((diameter/2)**2)
Dark2_colors=['seagreen','chocolate','slateblue','deeppink','yellowgreen']

# 假设sheetnames是已定义的工作表名称列表
sheetnames = ["sheet1", "sheet2", "sheet3", "sheet4"]

for i in np.arange(0,len(sheetnames),1):
    label=sheetnames[i]
    df = pd.read_excel('filename.xlsx',sheet_name = sheetnames[i] ,header= None)
    df = df.iloc[3:] #移除前3行
    df.rename(columns = {0:'Standard travel[mm]', 1:'Standard force[N]'},inplace=True)#重命名列

    df['Strain']=(df['Standard travel[mm]']/height)*100
    df['Stress']=(df['Standard force[N]']/Circle_area)

    y = df['Stress']
    x = df['Strain']

    if i==0:
        axes[0,0].plot(x, y, linewidth=1, c=Dark2_colors[i], label=label)
              
    elif i==1:
        axes[0,1].plot(x, y, linewidth=1, c=Dark2_colors[i], label=label)
   
    elif i==2:
        axes[1,0].plot(x, y, linewidth=1, c=Dark2_colors[i], label=label)

    elif i==3:
        axes[1,1].plot(x, y, linewidth=1, c=Dark2_colors[i], label=label)

for ax in axes.flat:
    ax.set_xlabel('Compressive Strain [%]',fontsize=14,fontweight='bold')
    ax.set_ylabel('Compressive Stress [MPa]',fontsize=14,fontweight='bold')
 
for ax in axes.flat:
    ax.label_outer()
    
for ax in axes.flat:
    ax.legend()

plt.show()

注:原代码中plot函数存在多余逗号,已修正;同时添加了label参数,确保图例正常显示。

问题原因

Matplotlib默认会根据每个子图的数据集范围自动计算并设置Y轴刻度,当不同子图的数据范围存在差异时,就会出现刻度不一致的情况。

解决方案

方法1:共享Y轴刻度(最简单)

在创建子图时设置sharey=True,让所有子图共享同一个Y轴刻度,Matplotlib会自动基于所有数据的范围统一设置刻度:

fig, axes = plt.subplots(2, 2, constrained_layout=True, 
                        figsize=(7,7), sharey=True)

这样所有子图的Y轴会使用相同的刻度范围,无需额外计算。

方法2:手动统一Y轴范围

如果需要更精细地控制刻度范围,可以先遍历所有数据,计算出全局的Y轴最小值和最大值,再统一设置所有子图的Y轴范围:

# 先收集所有Y轴数据
all_stress = []
for sheet in sheetnames:
    df = pd.read_excel('filename.xlsx', sheet_name=sheet, header=None)
    df = df.iloc[3:]
    df.rename(columns={0:'Standard travel[mm]', 1:'Standard force[N]'}, inplace=True)
    df['Stress']=(df['Standard force[N]']/Circle_area)
    all_stress.extend(df['Stress'].values)

# 计算全局的最小和最大值
global_min = np.min(all_stress)
global_max = np.max(all_stress)

# 绘制子图(部分代码省略,和原代码一致)

# 统一设置所有子图的Y轴范围
for ax in axes.flat:
    ax.set_ylim(global_min, global_max)

这种方法适合需要自定义刻度范围的场景,比如希望给最大值留出一定余量,可以将global_max乘以1.1。

内容的提问来源于stack exchange,提问作者Ouriel Bliah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 05:30:19