Matplotlib 数据可视化教程
笔记
第一部分:Matplotlib基础概念
1. Matplotlib简介
1.1 什么是Matplotlib?
Matplotlib 是 Python 中最流行的数据可视化库之一,由 John D. Hunter 于 2003 年创建。它的核心功能是通过编程生成静态、动态或交互式的图表,支持多种输出格式(如 PNG、PDF、SVG)。
- 主要特点:
- 支持多种图表类型(折线图、散点图、柱状图、饼图等)。
- 高度可定制化(颜色、标签、标题、网格、图例等)。
- 与 NumPy、Pandas 无缝集成,适合科学计算和数据分析。
- 提供面向对象和类 MATLAB 风格的两种编程接口。
1.2 核心组件
Matplotlib 的结构基于分层对象模型,关键组件包括:
Figure(画布):
所有图表的顶层容器,可理解为一张空白画纸。通过plt.figure()创建。fig = plt.figure(figsize=(8, 4)) # 设置画布大小(宽8英寸,高4英寸)Axes(坐标系):
在Figure上创建的绘图区域,包含坐标轴、标签、数据图形等。一个Figure可以包含多个Axes。ax = fig.add_subplot(1, 1, 1) # 在画布上添加一个子图Axis(坐标轴):
控制Axes的坐标轴范围、刻度、标签等。例如ax.xaxis.set_ticks()。Artist(元素):
所有可见元素的基类,包括文本、线条、矩形等。用户可通过Artist对象精细控制图表细节。
1.3 两种编程接口
Matplotlib 提供两种风格的 API,适应不同需求:
- 面向对象(OO)风格:
显式创建Figure和Axes对象,适合复杂图表和脚本编程。fig, ax = plt.subplots() # 创建画布和坐标系 ax.plot([1, 2, 3], [4, 5, 6]) # 在坐标系中绘图 ax.set_xlabel("X Axis") # 设置坐标轴标签 - 类 MATLAB 风格:
使用pyplot模块的全局状态机接口,语法类似 MATLAB,适合快速绘图。plt.plot([1, 2, 3], [4, 5, 6]) # 直接绘图 plt.xlabel("X Axis") # 全局设置标签 plt.show() # 显示图表 - 对比与选择:
- OO 风格:推荐用于复杂图表、多子图布局或需要复用的代码。
- MATLAB 风格:适合快速交互式绘图(如 Jupyter Notebook 中的简单可视化)。
1.4 与其他可视化库的对比
- Seaborn:
- 基于 Matplotlib,提供更高级的统计图表接口(如热力图、分布图)。
- 默认样式更美观,适合数据探索。
- Plotly/Bokeh:
- 支持交互式图表(缩放、悬停提示),适合 Web 应用。
- 语法与 Matplotlib 差异较大,学习曲线较陡。
- Matplotlib 的定位:
- 灵活性强,但 API 较为底层,适合需要高度定制的场景。
2. 安装与环境配置
2.1 安装 Matplotlib
- 通过 pip 安装:
pip install matplotlib - 通过 conda 安装:
conda install matplotlib - 验证安装:
import matplotlib print(matplotlib.__version__) # 输出版本号,如 3.7.1
2.2 Jupyter Notebook 配置
- 内嵌显示图表:
在 Notebook 单元格中运行以下代码,使图表直接嵌入输出区域:%matplotlib inline - 调整分辨率:
%config InlineBackend.figure_format = 'retina' # 支持高分辨率显示
2.3 常见 IDE 支持
- PyCharm:
- 需在代码末尾调用
plt.show()以显示图表。 - 配置科学模式(Scientific Mode)可实时预览图表。
- 需在代码末尾调用
- VS Code:
- 安装 Python 扩展后,直接运行代码即可在窗口内显示图表。
- 使用
# %%分隔代码单元格,支持交互式绘图。
2.4 常见问题解决
- 中文显示乱码:
需手动指定中文字体(如 SimHei、Microsoft YaHei):plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体 plt.rcParams['axes.unicode_minus'] = False # 解决负号显示异常 - 图表不显示:
- 确保在脚本中调用
plt.show()。 - 在 Notebook 中检查是否运行了
%matplotlib inline。
- 确保在脚本中调用
第二部分:基础绘图
1. 快速绘制第一张图
1.1 基本绘图流程
Matplotlib 最简单的绘图流程仅需 3 步:
- 导入库:
import matplotlib.pyplot as plt - 绘制数据:
plt.plot([x数据], [y数据]) - 显示图表:
plt.show()
示例代码:
import matplotlib.pyplot as plt
# 数据(省略x轴时,默认使用索引作为x值)
y = [2, 4, 1, 5]
plt.plot(y) # 绘制折线图
plt.ylabel("数值") # 添加y轴标签
plt.title("简单折线图") # 添加标题
plt.show() # 显示图表
输出效果:
- 生成一条以索引
[0, 1, 2, 3]为 x 轴,[2, 4, 1, 5]为 y 轴的折线图。
2. 常用图表类型
Matplotlib 支持多种基础图表类型,以下是核心图表及其用法:
2.1 折线图 (plt.plot)
- 功能:显示数据随时间或其他连续变量的变化趋势。
- 关键参数:
color:颜色(如'r'或'#FF5733')linestyle:线型(如'--'虚线、':'点线)marker:数据点标记(如'o'圆圈、's'方块)linewidth:线宽(如2.0)
示例:多线叠加折线图
import numpy as np
x = np.linspace(0, 2*np.pi, 50)
y1 = np.sin(x)
y2 = np.cos(x)
plt.plot(x, y1, color='blue', linestyle='-', label='sin(x)')
plt.plot(x, y2, color='red', linestyle='--', marker='o', label='cos(x)')
plt.xlabel("x 轴")
plt.ylabel("y 轴")
plt.legend() # 显示图例
plt.grid(True) # 显示网格
plt.show()
2.2 散点图 (plt.scatter)
- 功能:展示两个变量之间的相关性或分布。
- 关键参数:
s:点的大小(标量或数组)c:颜色(支持单色或颜色映射)alpha:透明度(0~1)cmap:颜色映射(如'viridis')
示例:颜色映射散点图
x = np.random.randn(100)
y = np.random.randn(100)
colors = np.random.rand(100) # 随机颜色值
sizes = 100 * np.random.rand(100) # 随机大小
plt.scatter(x, y, c=colors, s=sizes, alpha=0.6, cmap='viridis')
plt.colorbar() # 显示颜色条
plt.xlabel("X 变量")
plt.ylabel("Y 变量")
plt.title("散点图示例")
plt.show()
2.3 柱状图 (plt.bar)
- 功能:比较不同类别的数值大小。
- 关键参数:
width:柱宽(默认 0.8)align:对齐方式('center'或'edge')edgecolor:边框颜色hatch:填充图案(如'//'斜线)
示例:分组柱状图
labels = ['A', 'B', 'C', 'D']
values1 = [20, 35, 30, 25]
values2 = [15, 32, 34, 20]
x = np.arange(len(labels)) # 生成索引 [0,1,2,3]
width = 0.35 # 柱宽
plt.bar(x - width/2, values1, width, label='组1', edgecolor='black')
plt.bar(x + width/2, values2, width, label='组2', hatch='//')
plt.xticks(x, labels) # 设置x轴刻度标签
plt.legend()
plt.title("分组柱状图")
plt.show()
2.4 饼图 (plt.pie)
- 功能:显示各类别占比。
- 关键参数:
explode:突出显示某部分(如[0.1, 0, 0, 0])autopct:显示百分比格式(如'%1.1f%%')shadow:添加阴影startangle:起始角度(0~360)
示例:带百分比和突出效果的饼图
sizes = [30, 25, 15, 20, 10]
labels = ['A', 'B', 'C', 'D', 'E']
explode = [0.1, 0, 0, 0, 0] # 突出第一块
plt.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
shadow=True, startangle=90)
plt.axis('equal') # 保证饼图为正圆
plt.title("饼图示例")
plt.show()
2.5 直方图 (plt.hist)
- 功能:展示数据分布和频次。
- 关键参数:
bins:分箱数量(决定柱的精细度)range:数据范围(如(0, 100))density:是否显示概率密度(取代频次)histtype:类型('bar','step','stepfilled')
示例:概率密度直方图
data = np.random.normal(0, 1, 1000) # 生成正态分布数据
plt.hist(data, bins=30, density=True, alpha=0.7, edgecolor='black')
plt.xlabel("数值区间")
plt.ylabel("概率密度")
plt.title("正态分布直方图")
plt.show()
2.6 箱线图 (plt.boxplot)
- 功能:展示数据分布的五数概括(最小值、第一四分位、中位数、第三四分位、最大值)及离群值。
- 关键参数:
notch:是否显示中位数的置信区间(凹口)vert:方向(True为垂直,False为水平)patch_artist:是否填充箱体颜色
示例:多组数据箱线图
data = [np.random.normal(0, 1, 100),
np.random.normal(2, 1.5, 100),
np.random.normal(-1, 0.5, 100)]
plt.boxplot(data, notch=True, patch_artist=True, labels=['组1', '组2', '组3'])
plt.ylabel("观测值")
plt.title("多组箱线图")
plt.grid(True, linestyle='--', alpha=0.5)
plt.show()
3. 图表元素定制
3.1 标题与坐标轴
- 方法:
plt.title("标题")plt.xlabel("X 轴标签")plt.ylabel("Y 轴标签")
- 参数:
fontsize:字体大小(如14)color:颜色(如'#333333')
示例:
plt.plot([1, 2, 3], [4, 5, 1])
plt.title("自定义标题", fontsize=16, color='blue')
plt.xlabel("X 轴", fontsize=12, color='gray')
plt.ylabel("Y 轴", fontsize=12, color='gray')
plt.show()
3.2 坐标轴范围与刻度
- 方法:
plt.xlim(0, 10):设置 x 轴范围plt.ylim(-5, 5):设置 y 轴范围plt.xticks([0, 1, 2], ['A', 'B', 'C']):自定义刻度标签
示例:
x = np.linspace(0, 2*np.pi, 100)
plt.plot(x, np.sin(x))
plt.xlim(0, 2*np.pi) # 设置x轴范围
plt.xticks([0, np.pi/2, np.pi, 3*np.pi/2, 2*np.pi],
['0', 'π/2', 'π', '3π/2', '2π']) # 自定义刻度
plt.title("正弦波")
plt.show()
3.3 图例 (plt.legend)
- 参数:
loc:位置(如'upper left'、'best')ncol:列数(多列排列图例)frameon:是否显示边框
示例:多列图例
x = np.linspace(0, 10, 100)
plt.plot(x, x**2, label='二次函数')
plt.plot(x, x**3, label='三次函数')
plt.legend(loc='upper center', ncol=2, frameon=False)
plt.show()
3.4 网格与注释
- 网格:
plt.grid(True, linestyle='--', alpha=0.5) - 文本注释:
plt.text(x, y, "文本"):在指定坐标添加文本plt.annotate("注释", xy=(x,y), xytext=(tx,ty), arrowprops=dict(arrowstyle="->"))
示例:添加箭头注释
plt.plot([1, 2, 3], [4, 5, 1])
plt.annotate('峰值', xy=(2,5), xytext=(1,6),
arrowprops=dict(facecolor='red', arrowstyle='->'))
plt.text(3, 1, '最低点', color='blue')
plt.grid(True, linestyle=':', alpha=0.7)
plt.show()
第三部分:高级绘图与布局
1. 多图布局
Matplotlib 支持在单张画布中创建多个子图,适用于对比分析或复杂数据展示。
1.1 使用 plt.subplots() 创建子图
- 基本语法:
返回一个fig, axes = plt.subplots(nrows=行数, ncols=列数, figsize=(宽, 高))Figure对象和包含子图Axes对象的数组。
示例:2x2 子图布局
fig, axes = plt.subplots(2, 2, figsize=(10, 6)) # 2行2列
axes[0,0].plot([1, 2, 3], [1, 4, 9]) # 左上子图
axes[0,0].set_title("子图1")
axes[0,1].scatter(np.random.rand(10), np.random.rand(10)) # 右上子图
axes[1,0].bar(['A', 'B', 'C'], [3, 7, 2]) # 左下子图
axes[1,1].hist(np.random.randn(1000), bins=30) # 右下子图
plt.tight_layout() # 自动调整子图间距
plt.show()
1.2 使用 GridSpec 实现复杂布局
- 功能:自由定义子图的位置和大小比例。
- 示例:左侧大图 + 右侧两行小图
import matplotlib.gridspec as gridspec
fig = plt.figure(figsize=(10, 6))
gs = gridspec.GridSpec(2, 2, width_ratios=[3, 1], height_ratios=[1, 2]) # 定义网格比例
ax1 = fig.add_subplot(gs[:, 0]) # 左侧占所有行
ax2 = fig.add_subplot(gs[0, 1]) # 右上方
ax3 = fig.add_subplot(gs[1, 1]) # 右下方
ax1.plot(np.random.randn(100)) # 主图
ax2.pie([30, 70], labels=['A', 'B']) # 右上饼图
ax3.barh(['X', 'Y'], [5, 3]) # 右下水平柱状图
plt.tight_layout()
1.3 共享坐标轴
- 应用场景:多子图共享 x 轴或 y 轴,避免重复刻度。
- 方法:
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True) # 共享x轴 ax1.plot(x, y1) ax2.plot(x, y2)
2. 样式与主题
2.1 预定义样式
Matplotlib 内置多种样式,一键切换全局风格:
plt.style.use('ggplot') # 可选样式:'seaborn', 'dark_background', 'fivethirtyeight'等
- 查看所有可用样式:
print(plt.style.available)
2.2 自定义全局配置 (rcParams)
- 调整字体、颜色、线宽等全局参数:
plt.rcParams.update({ 'font.size': 12, # 全局字体大小 'axes.titlesize': 16, # 标题字体大小 'axes.labelsize': 14, # 坐标轴标签大小 'lines.linewidth': 2, # 线宽 'grid.color': '0.8', # 网格颜色 })
3. 颜色与标记
3.1 颜色映射 (Colormap)
- 应用场景:在散点图、热力图中用颜色表示数据强度。
- 示例:散点图颜色映射
x = np.random.rand(100)
y = np.random.rand(100)
colors = np.random.rand(100) # 颜色值范围0~1
plt.scatter(x, y, c=colors, cmap='viridis') # 使用'viridis'颜色映射
plt.colorbar(label='强度') # 添加颜色条
3.2 自定义颜色列表
- 直接指定颜色:
plt.plot(x, y, color='#FF5733') # 十六进制颜色 plt.bar(labels, values, color=['red', 'green', 'blue']) # 不同柱子不同颜色
4. 高级图表
4.1 双纵坐标轴
- 方法:
ax.twinx()创建共享 x 轴的第二个 y 轴。
fig, ax1 = plt.subplots()
# 第一个y轴(左侧)
ax1.plot(x, y1, color='blue', label='温度')
ax1.set_ylabel('温度 (°C)')
# 第二个y轴(右侧)
ax2 = ax1.twinx()
ax2.plot(x, y2, color='red', label='湿度')
ax2.set_ylabel('湿度 (%)')
plt.title("双纵坐标轴示例")
fig.legend(loc='upper left') # 合并图例
plt.show()
4.2 误差线 (plt.errorbar)
- 功能:显示数据点的误差范围。
x = np.arange(5)
y = [2, 3, 1, 4, 2]
y_err = [0.3, 0.4, 0.2, 0.6, 0.1]
plt.errorbar(x, y, yerr=y_err, fmt='o', capsize=5, label='数据')
plt.xlabel("X轴")
plt.ylabel("Y轴")
plt.legend()
plt.show()
4.3 极坐标图
- 方法:通过
projection='polar'切换为极坐标系。
theta = np.linspace(0, 2*np.pi, 100)
r = np.sin(3*theta) # 三叶玫瑰线
plt.subplot(111, projection='polar') # 极坐标子图
plt.plot(theta, r)
plt.title("极坐标图示例")
plt.show()
4.4 3D 绘图
- 步骤:导入
mplot3d工具包,创建 3D 坐标系。
from mpl_toolkits import mplot3d
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d') # 创建3D坐标系
# 生成数据
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))
# 绘制3D曲面
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
ax.set_zlabel('Z轴')
plt.title("3D曲面图")
plt.show()
5. 实战技巧
5.1 调整子图间距
- 方法:
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1, wspace=0.3, hspace=0.4)wspace:水平间距hspace:垂直间距
5.2 保存高清图表
- 参数:
plt.savefig('output.png', dpi=300, bbox_inches='tight', transparent=True)dpi:分辨率(每英寸点数)bbox_inches:去除多余白边
更多推荐
所有评论(0)