前言:
Matplotlib 是 Python 数据可视化领域最基础、功能最强大的库之一,而 matplotlib.pyplot 则为其提供了一个类似 MATLAB 的绘图接口 。无论你是做数据探索、算法调试,还是撰写论文、发布报告,掌握 pyplot 的用法都能让你高效地生成高质量图形。
一. 环境准备与核心概念
1.1 安装与导入
如果你尚未安装 Matplotlib,可以使用 pip 进行安装:
python
pip install matplotlib
在代码中,我们通常按以下方式导入 pyplot:
python
import matplotlib.pyplot as plt
1.2 Figure 与 Axes ------ 理解绘图的"容器"
在 pyplot 中,两个最重要的概念是 Figure 和 Axes:
-
Figure(画布):代表整个图形窗口或图形对象。它可以包含一个或多个子图(即 Axes)。
-
Axes(坐标系):代表一个独立的绘图区域,包含 x 轴、y 轴、刻度、标签等。每个 Axes 都有一个数据空间,我们正是在 Axes 上进行线条、散点、柱状等图形的绘制。
容易混淆 pyplot 的"状态机"接口(如 plt.plot())和面向对象接口(如 ax.plot())。前者隐式地使用"当前"Figure 和 Axes,简单快速;后者则更清晰、适合复杂布局。本文会同时介绍两种方式,并指出它们的关系。
二. 最简单的折线图与基本控制
2.1 使用 plt.plot() 绘制折线
python
import matplotlib.pyplot as plt
# 准备数据
x = [1, 2, 3, 4, 5]
y = [2, 4, 1, 7, 3]
# 绘制折线图(状态机风格)
plt.plot(x, y)
# 显示图形
plt.show()
效果:

2.2 增加标题、轴标签与网格
为了让图形信息完整,必须添加轴标签和图标题:

-
xlabel()/ylabel()设置横纵轴的文字说明。 -
title()为图形设置一个概括性标题。 -
grid(True)绘制背景网格线,默认采用主刻度位置。
2.3 自定义线条样式与颜色
plot() 函数接受可选的格式字符串 或关键字参数来控制线条外观。常用的格式字符串如 'r--' 表示红色虚线,'go' 表示绿色圆点标记(无线条)。
python
plt.plot(x, y, color='red', linestyle='dashed', linewidth=2, marker='o', markersize=8)
plt.show()
效果:

python
plt.rcParams['font.sans-serif'] = ['SimHei'] #设置中文字体 和中文
plt.figure(figsize=(10,5)) #设置画布大小
# plt.grid()#网格线
plt.grid(linestyle='--',alpha=0.8)#网格线虚线---透明度
# plt.legend(['北京','上海','哈尔滨']) #右上角图例解释
plt.legend(loc='upper right') #绘制折线加上label loc 设置上下左右

| 参数 | 说明 | 常用取值 |
|---|---|---|
color |
线条颜色 | 'red', 'blue', '#FF5733' 等 |
linestyle |
线型 | '-' (实线), '--' (虚线), ':' (点线) |
linewidth |
线宽(磅值) | 浮点数,如 1.5 |
marker |
数据点标记样式 | 'o' (圆点), 's' (方块), '^' (三角形) |
markersize |
标记大小 | 数值 |
三. 多种图形类型的绘制方法
除了折线图,pyplot 还提供了一系列函数用于创建不同的统计图表。
3.1 散点图:plt.scatter()
散点图适用于展示两个变量之间的相关关系或数据分布。
python
x = [5, 7, 8, 6, 9, 10, 12]
y = [8, 9, 10, 7, 11, 13, 14]
plt.scatter(x, y, color='purple', s=50, alpha=0.6)
plt.xlabel("实验组")
plt.ylabel("对照组")
plt.title("散点图示例")
plt.show()
效果

-
s:点的大小(面积,以像素平方为单位)。 -
alpha:透明度(0 完全透明,1 完全不透明),适合重叠点较多的数据。
3.2 柱状图:plt.bar()
柱状图常用于比较不同类别的数值。
python
categories = ['A', 'B', 'C', 'D']
values = [23, 45, 18, 36]
plt.bar(categories, values, color='skyblue', edgecolor='black')
plt.xlabel("类别")
plt.ylabel("数值")
plt.title("柱状图示例")
plt.show()
效果

如需绘制水平柱状图,可使用 plt.barh()。

3.3 直方图:plt.hist()
直方图用于展示连续变量的分布情况,将数据划分成若干个区间(bins)。
python
import numpy as np
# 生成 1000 个服从正态分布的随机数据
data = np.random.randn(1000)
plt.hist(data, bins=30, edgecolor='black', alpha=0.7)
plt.xlabel("数值")
plt.ylabel("频数")
plt.title("直方图(正态分布)")
plt.show()
效果
-
bins:区间的数量或具体的边界列表。 -
density=True:将纵轴转换为概率密度(所有条形面积之和为 1)。
3.4 箱线图:plt.boxplot()
箱线图展示数据的中位数、四分位数以及异常值。
python
# 生成三组不同分布的数据
data1 = np.random.normal(0, 1, 100)
data2 = np.random.normal(2, 1.5, 100)
data3 = np.random.normal(-1, 0.8, 100)
plt.boxplot([data1, data2, data3], labels=['组1', '组2', '组3'])
plt.ylabel("测量值")
plt.title("箱线图比较")
plt.show()
效果

箱体的上下边缘分别代表第一四分位数(Q1)和第三四分位数(Q3);箱体中间的线是中位数;上下触须通常表示 Q1-1.5IQR 和 Q3+1.5IQR 范围内的极值;超出触须的点被视为异常值。
四. 图例与多数据系列对比
在同一坐标系中绘制多条曲线或不同类别数据时,必须使用图例加以区分。
python
x = np.linspace(0, 10, 100) # 生成 0 到 10 之间 100 个等间距点
y1 = np.sin(x)
y2 = np.cos(x)
plt.plot(x, y1, label='sin(x)', linewidth=2)
plt.plot(x, y2, label='cos(x)', linestyle='--', linewidth=2)
plt.xlabel("x")
plt.ylabel("y")
plt.title("正弦与余弦曲线")
plt.legend(loc='upper right') # 显示图例,loc 指定位置
plt.grid(True)
plt.show()
效果

-
label参数在plot中指定曲线的名称。 -
legend()将根据所有已标记的艺术家对象自动创建图例。loc可选'best','upper left','lower right'等。
五. 子图:在一张画布上组织多个坐标系
当需要并列展示多个图形时,使用 plt.subplot() 或 plt.subplots() 创建子图。
5.1 使用 plt.subplot() 逐个添加
subplot(nrows, ncols, index) 将画布分割成 nrows 行 ncols 列的子图网格,并选中第 index 个子图作为当前活动坐标系。
python
# 第一个子图:2 行 1 列的第 1 个
plt.subplot(2, 1, 1)
plt.plot([1,2,3], [1,4,9])
plt.title("子图 1")
# 第二个子图:2 行 1 列的第 2 个
plt.subplot(2, 1, 2)
plt.plot([1,2,3], [1,2,1])
plt.title("子图 2")
plt.tight_layout() # 自动调整子图间距,防止重叠
plt.show()
效果

tight_layout() 是避免轴标签、标题相互遮挡的常用函数。
5.2 更强大的 plt.subplots()(面向对象风格)
plt.subplots() 一次生成所有的 Figure 和 Axes 对象,返回一个包含所有 Axes 的 NumPy 数组,便于统一配置。
python
fig, axes = plt.subplots(2, 2, figsize=(8, 6)) # 2行2列,画布大小8x6英寸
# axes 是一个 2x2 的二维数组,axes[0,0] 表示第1行第1个子图
# 在左上角子图上绘图
axes[0, 0].plot([0,1], [0,1], 'r-')
axes[0, 0].set_title("线性")
# 在右上角子图上绘图
axes[0, 1].scatter([0,1,2], [0,1,0], color='blue')
axes[0, 1].set_title("散点")
# 左下角子图
axes[1, 0].bar(['A','B'], [3,5], color='green')
axes[1, 0].set_title("柱状")
# 右下角子图
axes[1, 1].hist(np.random.randn(200), bins=20, color='orange')
axes[1, 1].set_title("直方图")
plt.tight_layout()
plt.show()
效果

使用面向对象接口时,所有设置函数均以 set_* 形式存在,例如 set_title(), set_xlabel(),这与 plt.title() 等状态机函数对应。
六. 精细调整:刻度、标签旋转与文本标注
6.1 修改刻度位置与标签
有时默认的刻度间隔不符合需求,可以使用 plt.xticks() 或面向对象的 set_xticks() / set_xticklabels()。
python
x = np.arange(0, 101, 10)
y = x ** 2
plt.plot(x, y)
# 设置 x 轴刻度位置为 0, 20, 40, 60, 80, 100
plt.xticks([0, 20, 40, 60, 80, 100])
# 可以同时设置刻度标签的文字
plt.yticks([0, 2000, 4000, 6000, 8000, 10000], ['0', '2k', '4k', '6k', '8k', '10k'])
plt.show()
效果

6.2 旋转刻度标签(防止重叠)
当类别标签文本较长时,旋转角度可以让布局更美观。
python
categories = ['非常长的类别 A', '非常长的类别 B', '非常长的类别 C']
values = [10, 25, 15]
plt.bar(categories, values)
plt.xticks(rotation=45) # 旋转 45 度
# 或者调整水平对齐方式
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.show()
效果

6.3 在图中添加文本注释
使用 plt.text() 或 plt.annotate() 可以在指定坐标处添加说明。
python
x = [1,2,3,4]
y = [1,4,9,16]
plt.plot(x, y, 'bo-')
# 在坐标 (2.5, 8) 处写文本
plt.text(2.5, 8, '增长速度加快', fontsize=10, bbox=dict(facecolor='yellow', alpha=0.5))
# 带箭头的标注
plt.annotate('最大值', xy=(4,16), xytext=(3,12),
arrowprops=dict(facecolor='black', shrink=0.05))
plt.show()
效果
annotate 的参数:
-
xy箭头指向的点(数据坐标)。 -
xytext文本的起始位置。 -
arrowprops控制箭头属性的字典。
七. 保存图形到文件
使用 plt.savefig() 可以将当前图形保存为多种常见格式(PNG, PDF, SVG, JPG 等)。
python
plt.plot([1,2,3], [1,4,9])
plt.xlabel("x")
plt.ylabel("y")
plt.savefig('my_figure.png', dpi=300, bbox_inches='tight')
效果

-
dpi:每英寸点数,控制图像分辨率(出版常用 300)。 -
bbox_inches='tight':自动裁剪图形周围的空白区域,让导出的图片更紧凑。
注意:savefig() 应在 show() 之前调用,因为 show() 可能会清空图形(取决于后端)。
八. 样式与美观:快速使用预设样式
Matplotlib 内置了多种美观的样式表,可通过 plt.style.available 查看所有可用样式。
python
print(plt.style.available[:5]) # 打印前五个样式名

应用样式只需在绘图前调用:
python
plt.style.use('ggplot') # 使用类似 ggplot2 的样式
# 或使用 'seaborn-v0_8', 'fivethirtyeight' 等
plt.plot([1,2,3], [1,4,9])
plt.show()
效果

之后的所有绘图都会自动应用该样式,极大提升图形的专业感。
九、集成与效用类:与数据分析生态无缝衔接
9.1、pandas: 内置的可视化捷径
pandas 是Python数据分析的基石,它自带的 .plot() 方法本质上就是 Matplotlib 的轻量级封装 ,让你可以无需导入 matplotlib.pyplot 就能快速绘制图表。
- 代码示例 :直接对 DataFrame 调用
plot()方法,非常直观。
python
import pandas as pd
import matplotlib.pyplot as plt
# 创建数据
df = pd.DataFrame({'Year': [2010, 2011, 2012, 2013],
'Sales': [100, 150, 130, 200]})
# 直接对 DataFrame 调用 plot 方法
df.plot(x='Year', y='Sales', kind='line', marker='o')
plt.title("pandas 内置绘图:年度销售额趋势")
plt.show()
效果

9.2、xarray: 多维数组的可视化伴侣
xarray 用于处理带标签的多维数组(常见于地球科学领域),它的 .plot() 方法同样基于 Matplotlib。
- 代码示例 :
xarray强大的地方在于,它能自动识别数据的维度并为坐标轴和图例添加有意义的标签。
效果

十. 一个完整的工作流程示例
下面综合以上知识,完成一个具有实际意义的数据可视化任务:绘制某商品 7 天的销量趋势,并添加均值辅助线、文本标注和自定义样式。
python
import matplotlib.pyplot as plt
import numpy as np
# 数据:周一到周日销量
days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
sales = [120, 135, 110, 145, 160, 210, 195]
plt.figure(figsize=(10, 5)) # 创建自定义大小的画布
plt.style.use('seaborn-v0_8-darkgrid')
# 绘制折线图,同时显示数据点
plt.plot(days, sales, marker='o', linestyle='-', linewidth=2, color='#2E86AB', label='日销量')
# 添加均值水平线
mean_sales = np.mean(sales)
plt.axhline(y=mean_sales, color='red', linestyle='--', linewidth=1.5, label=f'均值 ({mean_sales:.1f})')
# 标注周末销量激增
plt.annotate('周末高峰', xy=('Sat', 210), xytext=('Fri', 180),
arrowprops=dict(arrowstyle='->', color='gray'))
plt.xlabel('星期', fontsize=12)
plt.ylabel('销量(件)', fontsize=12)
plt.title('某商品一周销量趋势', fontsize=14, fontweight='bold')
plt.legend(loc='upper left')
plt.grid(True, alpha=0.3)
# 旋转 x 轴刻度标签防止重叠
plt.xticks(rotation=0)
plt.tight_layout()
plt.savefig('weekly_sales.png', dpi=150)
plt.show()
效果:

这个例子展示了实际项目中需要的大部分元素:数据准备、画布设置、样式、标注、图例、网格、保存。
结语
matplotlib.pyplot 是一个非常成熟且文档丰富的绘图库。本文涵盖了从创建第一个折线图到设计多子图、精细控制图形元素的全过程。值得强调的是:
-
状态机风格 (
plt.plot())适合快速探索数据,代码简洁; -
面向对象风格 (
fig, ax = plt.subplots())适合构建复杂的图形布局,逻辑更清晰; -
定制化能力是 Matplotlib 的最大优势,学习如何修改刻度、添加标注、调整图例位置等会让你的图形更符合专业出版要求。
以上均为个人观点!
以上均为个人观点!
以上均为个人观点!