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绘图的核心流程,我把它画成了流程图,方便你理解:
3.6 实用技巧总结
最后,分享几个我在项目中积累的小技巧:
- 保存图片用
savefig:设置dpi=300和bbox_inches='tight',避免图片被裁剪 - 中文字体问题:加一行
plt.rcParams['font.sans-serif'] = ['SimHei'],否则中文显示成方框 - 负号显示:加上
plt.rcParams['axes.unicode_minus'] = False - 颜色搭配:别用默认颜色,试试
#2E86AB、#A23B72这类高级灰
我的习惯:每次画图前,先想清楚这张图要表达什么信息。然后才动手写代码。数据可视化不是炫技,是沟通。你想想看,一张清晰的图表胜过千言万语。