3. Matplotlib基础:Figure与Axes对象、画布设置、基本绘图流程

各位同学,咱们今天来啃Matplotlib这块硬骨头。说实话,刚开始学数据可视化的时候,我也被Figure和Axes这两个概念绕晕过。后来在项目里画了几百张图,才真正搞明白它们的关系。今天我就把这点经验掰开揉碎了讲给你听。

3.1 核心概念:Figure与Axes

先打个比方。Figure就像一张画布,Axes就是画布上的绘图区域。一张画布上可以画多幅图,也就是多个Axes。我习惯把Figure想象成一张A4纸,Axes就是纸上用铅笔框出来的一个个小格子。

核心关系:

  • Figure:顶层容器,管理所有绘图元素
  • Axes:实际绘图区域,包含坐标轴、刻度、数据点
  • 一个Figure可以包含多个Axes
  • 每个Axes只能属于一个Figure

嗯,这里要注意:很多人把Axes和Axis搞混。Axes是绘图区域,Axis是坐标轴。我在代码评审时经常看到有人写plt.axis(),其实他想操作的是Axes对象。

3.2 画布设置:从空白到有图

咱们直接上代码。先创建一个最基本的画布:

import matplotlib.pyplot as plt

# 创建画布和绘图区域
fig, ax = plt.subplots(figsize=(8, 6))

# 设置画布属性
fig.set_facecolor('#f0f0f0')  # 背景色
fig.suptitle('我的第一张图', fontsize=16)  # 总标题

# 设置绘图区域属性
ax.set_xlabel('X轴标签')
ax.set_ylabel('Y轴标签')
ax.set_title('子图标题')
ax.grid(True, linestyle='--', alpha=0.7)

我个人习惯用plt.subplots()而不是plt.figure()。为什么?因为前者直接返回Figure和Axes对象,操作起来更顺手。我在项目中遇到过用plt.figure()画多子图时,坐标轴乱套的情况,后来全改成subplots了。

参数 说明 常用值
figsize 画布尺寸(宽,高),单位英寸 (8,6)、(10,8)
dpi 分辨率 100、150、300
facecolor 背景颜色 'white'、'#f5f5f5'
nrows/ncols 子图行列数 1、2、3

3.3 基本绘图流程:折线图

折线图是最常用的图表之一。说白了,就是把数据点用线连起来。来看一个完整的例子:

import matplotlib.pyplot as plt
import numpy as np

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

# 2. 创建画布
fig, ax = plt.subplots(figsize=(10, 6))

# 3. 绘制折线
ax.plot(x, y, 
        color='#2E86AB',      # 线条颜色
        linewidth=2,          # 线宽
        marker='o',           # 数据点标记
        markersize=6,         # 标记大小
        markerfacecolor='#A23B72',  # 标记填充色
        label='sin(x)')       # 图例标签

# 4. 美化图表
ax.set_title('正弦函数折线图', fontsize=14, pad=15)
ax.set_xlabel('X值', fontsize=12)
ax.set_ylabel('Y值', fontsize=12)
ax.legend(loc='best')
ax.grid(True, alpha=0.3)

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

避坑指南:我曾经在画折线图时,数据点太多导致线条密密麻麻。后来学会用markevery参数控制标记显示频率,比如markevery=5表示每5个点显示一个标记。这样图表清爽多了。

3.4 基本绘图流程:散点图

散点图适合展示两个变量之间的关系。你想想看,如果想知道身高和体重有没有关系,散点图就是最好的选择。

# 准备数据
np.random.seed(42)
x = np.random.randn(100)
y = 2 * x + np.random.randn(100) * 0.5

# 创建画布
fig, ax = plt.subplots(figsize=(8, 6))

# 绘制散点图
scatter = ax.scatter(x, y,
                     c=y,                # 根据y值着色
                     cmap='viridis',      # 颜色映射
                     s=50,               # 点的大小
                     alpha=0.7,          # 透明度
                     edgecolors='white',  # 边缘颜色
                     linewidth=0.5)       # 边缘线宽

# 添加颜色条
cbar = plt.colorbar(scatter, ax=ax)
cbar.set_label('颜色映射值', fontsize=10)

# 添加趋势线
z = np.polyfit(x, y, 1)
p = np.poly1d(z)
ax.plot(x, p(x), 'r--', alpha=0.8, label='趋势线')

ax.set_title('散点图示例:带趋势线', fontsize=14)
ax.set_xlabel('X变量', fontsize=12)
ax.set_ylabel('Y变量', fontsize=12)
ax.legend()
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

注意:散点图的数据点不宜过多。超过1000个点时,建议用alpha参数降低透明度,或者改用六边形分箱图(hexbin)。我曾经用散点图展示10万个点,结果图表卡得动不了,渲染出来也是一团黑。

3.5 知识体系结构图

下面这张图总结了Matplotlib绘图的核心流程,我把它画成了流程图,方便你理解:

Matplotlib绘图核心流程 1. 导入库 import matplotlib.pyplot as plt 2. 创建画布 fig, ax = plt.subplots() 3. 绘制数据 ax.plot() / ax.scatter() 4. 美化图表 标题/标签/图例/网格 关键参数 Figure参数: figsize, dpi, facecolor Axes参数: xlabel, ylabel, title plot参数: color, linewidth, marker scatter参数: c, s, alpha, cmap 常用方法: grid(), legend() tight_layout() savefig() 避坑提醒: 记得调用plt.show()

3.6 实用技巧总结

最后,分享几个我在项目中积累的小技巧:

  • 保存图片用savefig:设置dpi=300bbox_inches='tight',避免图片被裁剪
  • 中文字体问题:加一行plt.rcParams['font.sans-serif'] = ['SimHei'],否则中文显示成方框
  • 负号显示:加上plt.rcParams['axes.unicode_minus'] = False
  • 颜色搭配:别用默认颜色,试试#2E86AB#A23B72这类高级灰

我的习惯:每次画图前,先想清楚这张图要表达什么信息。然后才动手写代码。数据可视化不是炫技,是沟通。你想想看,一张清晰的图表胜过千言万语。

专注资料整理