3. Python 可视化工具:Matplotlib 基础架构、Figure 与 Axes 对象、基本绘图流程

Matplotlib 是 Python 数据可视化生态的基石。理解其核心架构——Figure(画布)与 Axes(坐标系/子图)——是构建任何复杂图表的前提。本节将拆解其对象层次,并演示标准绘图流程。

3.1 Matplotlib 三层架构

Matplotlib 采用分层设计,从底层到顶层依次为:后端(Backend)、Artist(渲染器) 和 pyplot(脚本层)。日常开发主要接触 pyplot 和 Artist 层。

层级 核心类/模块 职责 使用场景
脚本层 pyplot 提供类似 MATLAB 的状态机接口,自动管理 Figure 和 Axes 快速原型、交互式探索、简单图表
Artist 层 Figure, Axes, Line2D, Text 等 定义画布上的所有可见元素(图形、文字、刻度) 精细控制图表元素、定制化绘图
后端层 Renderer, FigureCanvas 处理底层渲染(屏幕显示、文件输出) 嵌入 GUI、生成特定格式、性能优化
核心原则: 始终记住 Figure 是容器,Axes 是实际绘图区域。一个 Figure 可以包含多个 Axes(子图),但每个 Axes 只能属于一个 Figure。

3.2 Figure 与 Axes 对象详解

3.2.1 Figure(画布)

Figure 是顶层容器,负责管理所有子图、标题、图例和画布属性。常用参数包括:

  • figsize:画布尺寸(英寸),元组 (width, height)。
  • dpi:分辨率(每英寸点数),影响清晰度。
  • facecolor:背景色。

3.2.2 Axes(坐标系/子图)

Axes 是实际的数据绘图区域,包含 X/Y 轴、刻度、网格以及所有数据图形(线、柱、点等)。每个 Axes 拥有独立的坐标空间。

关键区别: Axes 不是 Axis!Axis 是 Axes 内部的坐标轴对象(如 XAxis、YAxis),负责刻度位置和标签。初学者常混淆这两个概念。
Figure 与 Axes 对象层次结构 Figure(画布) fig = plt.figure(figsize=(10, 6)) Axes 1(子图1) ax1 = fig.add_subplot(1,2,1) X Axis Y Axis Axes 2(子图2) ax2 = fig.add_subplot(1,2,2) X Axis Y Axis 说明:一个 Figure 可包含多个 Axes;每个 Axes 拥有独立的坐标轴和数据图形。

3.3 基本绘图流程(四步法)

无论图表多复杂,Matplotlib 绘图都遵循以下四个标准步骤。掌握此流程,即可应对 90% 的日常绘图需求。

  1. 创建画布与子图: 使用 plt.subplots() 或 plt.figure() + fig.add_subplot() 创建 Figure 和 Axes 对象。
  2. 在 Axes 上绘图: 调用 Axes 的绘图方法(如 ax.plot(), ax.scatter(), ax.bar())绘制数据。
  3. 定制图表元素: 设置标题、轴标签、刻度、图例、网格等,提升可读性。
  4. 显示或保存: 使用 plt.show() 显示图表,或 fig.savefig() 保存为文件。
常见陷阱: 不要混用 plt 接口和 ax 接口!例如,使用 plt.title() 设置的是当前活跃 Axes 的标题,而 ax.set_title() 设置的是指定 Axes 的标题。在复杂布局中,始终优先使用面向对象的 ax 接口,避免状态机混乱。
Matplotlib 基本绘图流程(四步法) Step 1 创建画布与子图 fig, ax = plt.subplots() Step 2 在 Axes 上绘图 ax.plot(x, y) Step 3 定制图表元素 ax.set_title() Step 4 显示或保存 plt.show() 代码示例:完整四步法 fig, ax = plt.subplots() → ax.plot(x, y) → ax.set_title('标题') → plt.show()

3.4 完整代码示例:从数据到图表

以下代码演示了使用面向对象 API 完成一个完整折线图的绘制过程,包含数据准备、绘图、定制和保存。

import matplotlib.pyplot as plt
import numpy as np

# 1. 准备数据
x = np.linspace(0, 10, 100)
y = np.sin(x)

# 2. 创建画布和子图(Step 1)
fig, ax = plt.subplots(figsize=(8, 4), dpi=100)

# 3. 在 Axes 上绘图(Step 2)
ax.plot(x, y, color='#3498db', linewidth=2, label='sin(x)')

# 4. 定制图表元素(Step 3)
ax.set_title('正弦波示例', fontsize=14, fontweight='bold')
ax.set_xlabel('X 轴 (弧度)', fontsize=11)
ax.set_ylabel('Y 轴 (振幅)', fontsize=11)
ax.legend(loc='upper right')
ax.grid(True, linestyle='--', alpha=0.6)

# 5. 显示图表(Step 4)
plt.tight_layout()
plt.show()

# 可选:保存为文件
# fig.savefig('sine_wave.png', dpi=150, bbox_inches='tight')
最佳实践: 始终使用 plt.tight_layout() 自动调整子图间距,避免标签重叠。保存图片时使用 bbox_inches='tight' 去除多余白边。

3.5 常见绘图方法速查表

以下表格列出了最常用的 Axes 绘图方法及其适用场景,方便快速查阅。

方法 图表类型 典型参数 适用场景
ax.plot() 折线图 x, y, color, linewidth, label 趋势分析、时间序列
ax.scatter() 散点图 x, y, s, c, alpha 相关性分析、异常点检测
ax.bar() 柱状图 x, height, width, color 类别对比、分布统计
ax.hist() 直方图 x, bins, density, alpha 数据分布、频率统计
ax.boxplot() 箱线图 x, vert, patch_artist 异常值检测、数据分布对比
进阶提示: 在异常检测项目中,ax.scatter() 和 ax.boxplot() 是高频工具。散点图用于可视化异常点位置,箱线图用于快速识别离群值范围。