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

如何在循环生成的Matplotlib分面图中共享次Y轴

解决Matplotlib分面图次Y轴共享问题

问题描述

需通过循环指定行列数创建分面图,要求所有子图共享左侧主Y轴(对应ys数据)和右侧次Y轴(对应zs数据)。当前主Y轴与X轴已实现共享,但次Y轴未达到预期:刻度范围不统一,且标签显示不符合“仅外侧子图显示”的要求,需保留行列循环逻辑以适配大量子图场景。

解决方案

要让次Y轴与主Y轴表现一致,需完成两个核心操作:

  • 统一所有次Y轴的刻度范围:先计算所有次Y轴数据的全局极值,再为每个次Y轴设置相同刻度范围
  • 控制次Y轴刻度标签显示:仅保留最右侧列的子图显示次Y轴标签,其余子图仅显示刻度

修改后的代码

import numpy as np
import matplotlib.pyplot as plt

# 生成数据
x = np.arange(0, 10, 0.1)
y1 = x**2
y2 = 0.5 * x**2
y3 = 1.5 * x**2
y4 = 2 * x**2
ys = [y1, y2, y3, y4]  # 修正原代码变量名错误

z1 = -10 * y1
z2 = -11 * y2
z3 = -10.5 * y3
z4 = -9 * y4
zs = [z1, z2, z3, z4]

cols = 2
rows = 2
k = 0

# 初始化主图,共享X和主Y轴
fig, ax = plt.subplots(rows, cols, sharex=True, sharey=True, figsize=(10, 8))

# 计算次Y轴数据的全局极值,用于统一刻度范围
all_z_data = np.concatenate(zs)
z_min, z_max = all_z_data.min(), all_z_data.max()

for i in range(cols):
    for j in range(rows):
        # 绘制主Y轴数据
        ax[j, i].plot(x, ys[k], c='b')
        ax[j, i].tick_params(colors='b')

        # 创建次Y轴并绘制数据
        ax2 = ax[j, i].twinx()
        ax2.plot(x, zs[k], c='r')
        ax2.tick_params(colors='r')

        # 设置统一的次Y轴刻度范围
        ax2.set_ylim(z_min, z_max)

        # 控制次Y轴标签显示:仅最右侧列显示标签
        if i != cols - 1:
            ax2.set_yticklabels([])
        
        k += 1

plt.tight_layout()
plt.show()

关键说明

  • 统一刻度范围:通过np.concatenate(zs)合并所有次Y轴数据,计算全局最小/最大值后,用set_ylim()为每个次Y轴设置相同范围
  • 控制标签显示:通过判断列索引i是否为最后一列,决定是否隐藏次Y轴的刻度标签,保留刻度线
  • 修正原代码问题:原代码中变量y定义后使用时写为ys,已修正为统一的ys
  • 优化布局:添加plt.tight_layout()自动调整子图间距,避免标签重叠

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 20:40:17