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

Python Matplotlib为3×3布局所有子图添加断轴效果的实现方法

3×3布局子图批量添加断轴效果实现

原代码无法正常运行主要是几个核心问题:

  • 循环索引逻辑错误:三层嵌套循环里j没有递增规则,xx[j]取值会出错
  • 存在语法错误:均值计算语句多了冗余括号,且均值计算后的数组维度和x轴序列不匹配,无法直接绘图
  • 断轴视觉标识缺失:仅隐藏了上下边框,没有添加断轴斜切标记,无法识别断轴效果
  • 共享轴配置冲突:初始化子图时开启全局sharex/sharey,后续新增的断轴没有同步配置,会出现刻度错位、重复显示
  • 刻度未做隐藏处理:上方断轴的x轴刻度、标签没有隐藏,会和下方轴的刻度重叠

可直接运行的实现代码

下面的代码用模拟数据演示效果,你替换成自己的some_data和业务逻辑即可:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable

# -------------------------- 替换成你自己的数据 --------------------------
# 模拟数据维度对齐原代码的[op, pl, 时间序列]索引逻辑
some_data = np.concatenate([
    np.random.randint(0, 25, size=(3,3,13)),  # 低数值区间数据
    np.random.randint(50, 65, size=(3,3,13))  # 高数值区间数据
], axis=2)
xx = np.arange(13)
# -----------------------------------------------------------------------

fig, ax = plt.subplots(nrows=3, ncols=3, figsize=(17, 12), facecolor='white')
fig.subplots_adjust(hspace=0.3, wspace=0.25)

# 断轴斜切标记参数
slash_len = 0.015
slash_kwargs = dict(color='k', clip_on=False)

for pl in range(3):
    for op in range(3):
        # 为当前子图创建上方断轴
        divider = make_axes_locatable(ax[pl, op])
        ax_top = divider.new_vertical(size="100%", pad=0.1, sharex=ax[pl, op])
        fig.add_axes(ax_top)

        # 绘制下方轴(低数值段)
        ax[pl, op].plot(xx, np.mean(some_data[op, pl, :13], axis=0), "-x", color="red")
        ax[pl, op].set_ylim(0, 25)
        ax[pl, op].spines['top'].set_visible(False)
        ax[pl, op].tick_params(axis='x', top=False)

        # 绘制上方轴(高数值段)
        ax_top.plot(xx, np.mean(some_data[op, pl, 13:26], axis=0), "-x", color="blue")
        ax_top.set_ylim(50, 65)
        ax_top.spines['bottom'].set_visible(False)
        ax_top.tick_params(axis='x', bottom=False, labelbottom=False)

        # 添加断轴斜切标记
        slash_kwargs['transform'] = ax[pl, op].transAxes
        ax[pl, op].plot((-slash_len, slash_len), (-slash_len, slash_len), **slash_kwargs)
        ax[pl, op].plot((1-slash_len, 1+slash_len), (-slash_len, slash_len), **slash_kwargs)
        
        slash_kwargs['transform'] = ax_top.transAxes
        ax_top.plot((-slash_len, slash_len), (1-slash_len, 1+slash_len), **slash_kwargs)
        ax_top.plot((1-slash_len, 1+slash_len), (1-slash_len, 1+slash_len), **slash_kwargs)

        # 子图标题放在上方轴顶部,避免被轴间隙截断
        ax_top.set_title(f"pl={pl}, op={op}", pad=10)

# 统一设置所有子图x轴范围,实现全局x轴共享效果
for row in ax:
    for sub_ax in row:
        sub_ax.set_xlim(xx.min(), xx.max())

plt.show()

关键配置说明

  • 不要在plt.subplots初始化阶段直接开全局sharex/sharey,否则新增的断轴会出现刻度冲突,手动统一设置轴范围即可实现共享效果
  • 两个断轴段只绘制对应数值区间的数据,不要把全量数据同时画在两个轴上,避免出现线条截断异常
  • 斜切标记是断轴的核心视觉标识,不要省略
  • 如果需要做横向断轴,把new_vertical替换为new_horizontal,对应调整左右边框隐藏逻辑、断轴标记位置即可,这套逻辑支持任意行列数的子图网格,不限于3×3布局。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 19:36:24