Matplotlib面向对象API与pyplot对比及子图布局
请对比Matplotlib中pyplot状态机API和面向对象API(OO-API)的区别。为什么推荐在大项目中使用面向对象方式?如何灵活创建和布局多个子图?说明plt.subplots()、GridSpec和inset_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实现链式调用。