当前位置:首页 > 技术 > 正文内容

Python Matplotlib 多图与子图布局完全指南

访客 技术 2026年6月16日 1

参考文档:
https://matplotlib.org/3.5.3/tutorials/intermediate/arranging_axes.html

1. 创建多图的核心方法

在 Matplotlib 中,一个 axes 对象代表一个独立的绘图区域。官方文档将相关功能归类为 "arranging axes"(排列坐标轴)。

1.1 使用 subfigure 创建子图组

import matplotlib.pyplot as plt

# 启用 constrained_layout 自动处理边距和标签显示
fig = plt.figure(constrained_layout=True)
# 将图分割为 1 行 2 列的子图组,间距 0.07,宽度比例 1.5:1
subfigs = fig.subfigures(1, 2, wspace=0.07, width_ratios=[1.5, 1.])

1.2 通过 gridspec 精确控制网格

# 创建 3x3 的网格,并指定边距和间距
gs = fig.add_gridspec(nrows=3, ncols=3, 
                      left=0.05, right=0.75,
                      hspace=0.1, wspace=0.05)

1.3 subplots 快速生成多个子图

# 在网格的指定区域创建子图(前两行,所有列)
ax0 = fig.add_subplot(gs[:-1, :])

1.4 add_axes 手动添加任意位置坐标系

通过指定 [left, bottom, width, height](单位为 relative figure fractions),可以在现有图中自由嵌入小图:

# 在相对位置 (0.2, 0.2) 处创建一个宽度 0.5、高度 0.3 的小坐标系
ax = fig.add_axes([0.2, 0.2, 0.5, 0.3])

2. 实用示例代码

以下代码改编自官方文档,保留了核心逻辑但重构了变量命名和结构。

2.1 组合 subfigure + subplots

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure(constrained_layout=True, figsize=(10, 6))
# 创建左右两个子图组
subfigures = fig.subfigures(1, 2, wspace=0.08, width_ratios=[1.6, 1.0])

# 左侧子图组:2行2列,设置背景色和总标题
left_subfig = subfigures[0]
axs_left = left_subfig.subplots(2, 2)
left_subfig.set_facecolor('lightgray')
left_subfig.suptitle('Left Panel (2x2)')
left_subfig.supxlabel('Shared X Label')

# 右侧子图组:3行1列,设置标题
right_subfig = subfigures[1]
axs_right = right_subfig.subplots(3, 1)
right_subfig.suptitle('Right Panel (3x1)')
right_subfig.supylabel('Shared Y Label')

# 在左侧子图中填充示例数据
x = np.linspace(0, 2*np.pi, 100)
for i, ax in enumerate(axs_left.flat):
    ax.plot(x, np.sin(x + i*np.pi/4))
    ax.set_title(f'Sin(x + {i}π/4)')

plt.show()

2.2 通过 gridspec 灵活分配子图位置

import matplotlib.pyplot as plt

def annotate_axes(ax, text):
    """在坐标系上添加标注"""
    ax.text(0.5, 0.5, text, transform=ax.transAxes,
            ha='center', va='center', fontsize=14, fontweight='bold')

fig = plt.figure(constrained_layout=False, facecolor='lightyellow')
# 创建 3x3 网格
grid = fig.add_gridspec(nrows=3, ncols=3,
                        left=0.05, right=0.75,
                        hspace=0.1, wspace=0.05)

# ax0 占据前两行所有列
ax_main = fig.add_subplot(grid[:-1, :])
annotate_axes(ax_main, 'Main Plot (rows 0-1, all cols)')

# ax1 占据最后一行前两列
ax_bottom_left = fig.add_subplot(grid[-1, :-1])
annotate_axes(ax_bottom_left, 'Bottom Left')

# ax2 占据最后一行最后一列
ax_bottom_right = fig.add_subplot(grid[-1, -1])
annotate_axes(ax_bottom_right, 'Bottom Right')

fig.suptitle('Custom GridSpec Layout')
plt.show()

2.3 高级用法:子图嵌套与坐标轴控制

import matplotlib.pyplot as plt
import numpy as np

def waveform_generator(a, b, c, d, t=np.arange(0, 2*np.pi, 0.05)):
    """生成两个组合波形的 x,y 坐标"""
    x = np.sin(t*a) * np.cos(t*b)
    y = np.sin(t*c) * np.cos(t*d)
    return x, y

fig = plt.figure(figsize=(8, 8), constrained_layout=False)
# 创建外层 4x4 网格
outer_grid = fig.add_gridspec(4, 4, wspace=0, hspace=0)

for row in range(4):
    for col in range(4):
        # 每个外层网格单元内部再嵌套 3x3 子网格
        inner_grid = outer_grid[row, col].subgridspec(3, 3, wspace=0, hspace=0)
        # 生成该内部网格的所有子图
        axes_array = inner_grid.subplots()
        
        # 在每一个子图中绘制专属波形
        for (c, d), ax in np.ndenumerate(axes_array):
            x_data, y_data = waveform_generator(row+1, col+1, c+1, d+1)
            ax.plot(x_data, y_data)
            ax.set(xticks=[], yticks=[])  # 隐藏刻度

# 只显示最外层的坐标轴线
for ax in fig.get_axes():
    spec = ax.get_subplotspec()
    ax.spines.top.set_visible(spec.is_first_row())
    ax.spines.bottom.set_visible(spec.is_last_row())
    ax.spines.left.set_visible(spec.is_first_col())
    ax.spines.right.set_visible(spec.is_last_col())

plt.show()

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。