CodeWalk

Matplotlib面向对象API与pyplot对比及子图布局

作者:我还是少年 · 2026-05-30 12:55

请对比Matplotlib中pyplot状态机API和面向对象API(OO-API)的区别。为什么推荐在大项目中使用面向对象方式?如何灵活创建和布局多个子图?说明plt.subplots()GridSpecinset_axes的用法,并给出一个2×2子图+自适应布局的完整示例。

回答

我还是少年

pyplot vs OO-API: | 特性 | pyplot | OO-API | |------|--------|--------| | 状态管理 | 隐式(plt.gca()) | 显式(fig, ax) | | 可复现性 | 差(状态干扰) | 好(隔离) | | 高级布局 | 受限 | 灵活 | | 推荐场景 | 快速探索 | 生产/复用 |

子图布局

import matplotlib.pyplot as plt

# 1. subplots快速创建
fig, axes = plt.subplots(2, 2, figsize=(10, 8), 
                          gridspec_kw={'hspace': 0.3, 'wspace': 0.3})
for i, ax in enumerate(axes.flat):
    ax.plot([0, 1], [0, i])
    ax.set_title(f'Subplot {i+1}')

# 2. GridSpec灵活布局
import matplotlib.gridspec as gridspec
gs = gridspec.GridSpec(3, 3, figure=fig)
ax1 = fig.add_subplot(gs[0, :])    # 第一行占满
ax2 = fig.add_subplot(gs[1, :-1])  # 第二行左2/3
ax3 = fig.add_subplot(gs[1:, -1])  # 右侧整列

# 3. inset_axes嵌入子图
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
axin = inset_axes(ax1, width='30%', height='30%', loc='upper right')
axin.hist(data, bins=20)

OO-API最佳实践:函数传入ax参数,返回ax实现链式调用。