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

如何在Matplotlib主绘图的指定网格内精准嵌入子图?

精准嵌入子图到主图指定坐标区间的可复用方案

核心解决思路

通过Matplotlib的坐标转换机制,将主图中数据坐标(data)定义的矩形区域,转换成主图坐标轴的归一化坐标(axes),彻底避开边距、轴标签空间的干扰,实现子图与指定区域的精准对齐。同时封装成可复用函数,支持批量嵌入多网格子图。

完整可运行代码

import matplotlib.pyplot as plt
import numpy as np

def add_inset_to_data_region(ax_main, x_start, x_end, y_start, y_end, scale=0.8):
    """
    在主图指定的数据坐标区域内嵌入子图
    参数:
        ax_main: 主图的Axes对象
        x_start/x_end: 目标区域的x轴数据边界
        y_start/y_end: 目标区域的y轴数据边界
        scale: 子图在目标区域内的缩放比例(0-1,避免子图撑满区域)
    返回:
        ax_inset: 嵌入的子图Axes对象
    """
    # 步骤1:将数据坐标转换为屏幕像素坐标
    bl_pixel = ax_main.transData.transform((x_start, y_start))
    tr_pixel = ax_main.transData.transform((x_end, y_end))
    
    # 步骤2:将屏幕像素坐标转换为主图的归一化坐标轴坐标(0-1范围)
    ax_bl = ax_main.transAxes.inverted().transform(bl_pixel)
    ax_tr = ax_main.transAxes.inverted().transform(tr_pixel)
    
    # 步骤3:计算子图的位置与尺寸(居中放置)
    inset_width = (ax_tr[0] - ax_bl[0]) * scale
    inset_height = (ax_tr[1] - ax_bl[1]) * scale
    inset_left = ax_bl[0] + (ax_tr[0] - ax_bl[0] - inset_width) / 2
    inset_bottom = ax_bl[1] + (ax_tr[1] - ax_bl[1] - inset_height) / 2
    
    # 创建嵌入子图
    return ax_main.figure.add_axes([inset_left, inset_bottom, inset_width, inset_height])

# ------------------------------
# 示例1:单区域嵌入直方图
# ------------------------------
fig, ax = plt.subplots(figsize=(8, 6))

# 绘制主折线图
x = np.linspace(0, 5, 100)
y = np.sin(x) * 4 + 3
ax.plot(x, y, color="#1f77b4")
ax.set_xlabel("X轴标签")
ax.set_ylabel("Y轴标签")
ax.grid(True, alpha=0.3)

# 在x=3-4、y=3-4的区域嵌入无坐标轴直方图
inset_ax = add_inset_to_data_region(ax, 3, 4, 3, 4)
inset_ax.hist(np.random.normal(0, 1, 1000), bins=20, color="#ff7f0e")
# 隐藏子图坐标轴
inset_ax.set_xticks([])
inset_ax.set_yticks([])

plt.show()

# ------------------------------
# 示例2:多网格批量嵌入
# ------------------------------
fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(x, y, color="#1f77b4")
ax.set_xlabel("X轴标签")
ax.set_ylabel("Y轴标签")
ax.grid(True, alpha=0.3)

# 定义多个嵌入区域的坐标
embed_regions = [
    (1, 2, 2, 3),
    (3, 4, 0, 1),
    (0, 1, 4, 5)
]

# 批量嵌入子图
for region in embed_regions:
    inset_ax = add_inset_to_data_region(ax, *region)
    inset_ax.hist(np.random.randn(500), bins=15, color="#2ca02c")
    inset_ax.set_xticks([])
    inset_ax.set_yticks([])

plt.show()

关键细节说明

  • 坐标转换逻辑:先将数据坐标转成屏幕像素坐标,再转为主图的归一化坐标,完全不受主图边距、轴标签长度的影响,确保子图始终对齐指定的data区间。
  • 可复用性:函数支持自定义缩放比例,批量嵌入时只需循环传入不同的区域坐标即可,适配多网格场景。
  • 无坐标轴设置:通过set_xticks([])和set_yticks([])彻底隐藏子图坐标轴,符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:22:40