在数据分析与机器学习领域,"字不如表,表不如图"。数据可视化不仅能直观呈现数据内在规律,更是向业务方交付成果的关键桥梁。
Matplotlib 作为 Python 数据可视化领域的基石与开山鼻祖,也是应用最广泛的绘图库。无论是静态图表、动态交互还是高出版级期刊插图,Matplotlib 都能游刃有余地完成。
官方网站 :https://matplotlib.org
安装命令:
bash
pip install matplotlib
🛠️ 必备前置:彻底解决中文乱码与负号显示问题
在使用 Matplotlib 时,由于其默认字体不支持中文,常会出现方块乱码(□□);此外负号也可能显示异常。因此,在代码头部加入以下两行配置是标准规范:
python
import matplotlib.pyplot as plt
# 解决中文显示乱码(Windows常用 SimHei,Mac常用 Arial Unicode MS 或 PingFang SC)
plt.rcParams['font.sans-serif'] = ['SimHei']
# 解决负号 '-' 显示为方块的问题
plt.rcParams['axes.unicode_minus'] = False
🔍 一、 深度拆解:Matplotlib 图表的"解剖学"结构
要画好一张图,必须先理解一张图由哪些部件构成。Matplotlib 将一张图拆分为以下核心层级:
+-------------------------------------------------------+
| 画布 (Figure) |
| +-------------------------------------------------+ |
| | 标题 (Title) | |
| | Y轴标签 (Ylabel) [图例 (Legend)] | |
| | ^ | |
| | | / \ /\ [网格线 (Grid)] | |
| | |----+---+--+----+ | |
| | | / \/ \ | |
| | +------------------------> X轴 (Xaxis) | |
| | Y轴刻度/标签 X轴刻度/标签(Xtick_label) | |
| | X轴标签 (Xlabel) | |
| +-------------------------------------------------+ |
+-------------------------------------------------------+
核心要素对照表
| 组件名称 | 英文术语 | 对应控制 API | 核心作用 |
|---|---|---|---|
| 画布 | Figure | plt.figure() / plt.subplots() |
容纳所有视觉元素的顶级容器 |
| 坐标系/子图 | Axes | fig.add_subplot() / ax |
真正绘制图表的绘图区域(包含X/Y轴) |
| 标题 | Title | plt.title() / ax.set_title() |
图表的总体说明 |
| 轴线与标签 | Axis / Label | plt.xlabel(), plt.ylabel() |
说明坐标轴所代表的物理含义及单位 |
| 刻度与刻度标签 | Tick / Tick Label | plt.xticks(), plt.yticks() |
标定数值位置与具体文本标注 |
| 图例 | Legend | plt.legend() |
区分多条曲线或不同类别数据的标注说明 |
| 网格线 | Grid | plt.grid() |
辅助肉眼对齐数值和趋势判断 |
📈 二、 实战演练:绘制双城市气温变化曲线
下面通过一个双曲线折线图,把上述所有图表组件串联整合:
python
import matplotlib.pyplot as plt
import random
# 1. 解决中文与负号显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 2. 准备数据(1-24小时北京与西安的气温模拟)
x = range(1, 25)
y_beijing = [random.randint(10, 15) for _ in range(len(x))]
y_xa = [random.randint(15, 19) for _ in range(len(x))]
# 3. 绘制折线(设置标签 label 用于图例识别)
plt.plot(x, y_beijing, label='北京', color='#1f77b4', linewidth=2)
plt.plot(x, y_xa, label='西安', color='#ff7f0e', linewidth=2)
# 4. 图表辅助装饰
plt.title('24小时气温变化曲线', fontsize=14)
plt.xlabel('时间 (小时)', fontsize=12)
plt.ylabel('气温 (℃)', fontsize=12)
# 5. 添加网格线与图例
plt.grid(True, linestyle='--', alpha=0.5)
plt.legend(loc='upper right')
# 6. 设置坐标轴刻度及显示范围
plt.xticks(x[::2]) # X轴每2小时显示一个刻度
plt.yticks(range(5, 25, 2)) # Y轴从5℃到25℃,步长为2
# 7. 渲染输出
plt.show()
🧩 三、 画布进阶:多子图(Subplots)设计与管理
为了能同时展示多个图表,便于图表之间数据的直观对比和分析,更高效、更专业地组织和呈现复杂的可视化信息,通常会在一个画布上创建多个子图。
子图核心 API
python
figure, axes = plt.subplots(nrows=1, ncols=2, figsize=(20, 6), dpi=100)
nrows:子图行数ncols:子图列数figsize=(宽, 高):画布物理尺寸(英寸)dpi:每英寸点数(Dots Per Inch),控制图像分辨率清晰度axes:子图对象数组。如果是一行两列,axes[0]代表左图,axes[1]代表右图。
📊 四、 三大经典图表选型与实战
根据不同的业务场景,选用恰当的图表类型:
| 图表类型 | 对应 API | 核心优势 | 黄金应用场景 |
|---|---|---|---|
| 折线图 | plt.plot() / ax.plot() |
展示连续数据的趋势变化 | 气温变化、股价走势、时间序列分析 |
| 柱状图 | plt.bar() / ax.bar() |
突出离散类别的数量对比 | 各季度业绩、产品销量对比、各城市营收 |
| 饼状图 | plt.pie() / ax.pie() |
直观展示各部分的占比构成 | 用户画像年龄占比、市场份额、预算配比 |
综合案例:在一个画布中联动展示三大图表
python
import matplotlib.pyplot as plt
# 基础设置
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 创建 1 行 3 列的子图画布
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(18, 5), dpi=100)
# ----------------- 子图 1:折线图(趋势变化) -----------------
months = ['1月', '2月', '3月', '4月', '5月', '6月']
sales_trend = [120, 135, 170, 160, 210, 240]
axes[0].plot(months, sales_trend, marker='o', color='b', label='月销售额')
axes[0].set_title('上半年销售额趋势变化')
axes[0].set_xlabel('月份')
axes[0].set_ylabel('销售额(万元)')
axes[0].grid(True, linestyle=':', alpha=0.6)
axes[0].legend()
# ----------------- 子图 2:柱状图(数量对比) -----------------
categories = ['服装', '电子产品', '食品', '家居用品', '图书']
sales_count = [450, 310, 520, 180, 240]
axes[1].bar(categories, sales_count, color='#2ca02c', alpha=0.85)
axes[1].set_title('各品类销售数量对比')
axes[1].set_xlabel('产品类别')
axes[1].set_ylabel('销量(件)')
# ----------------- 子图 3:饼状图(占比构成) -----------------
channels = ['微信支付', '支付宝', '现金', '银行卡']
pay_ratio = [45, 35, 5, 15]
axes[2].pie(
pay_ratio,
labels=channels,
autopct='%1.1f%%',
startangle=140,
colors=['#ff9999', '#66b3ff', '#99ff99', '#ffcc99']
)
axes[2].set_title('各支付方式占比构成')
# 自动调整子图间距,防止重叠
plt.tight_layout()
plt.show()
📌 五、 核心知识点全景速查表
| 功能模块 | 核心 API / 语法 | 作用说明 | 关键参数 / 示例 |
|---|---|---|---|
| 全局设置 | plt.rcParams['font.sans-serif'] |
设置中文字体,防方块乱码 | ['SimHei'](黑体) |
plt.rcParams['axes.unicode_minus'] |
控制负号正常显示 | False |
|
| 画布与子图 | plt.subplots(nrows, ncols) |
创建网格化子图画布 | figsize=(宽, 高), dpi=100 |
plt.tight_layout() |
自动优化子图内边距排版 | 避免标题与轴标签重叠 | |
| 图表组件 | plt.title() / ax.set_title() |
设置图表主标题 | fontsize=14 |
plt.xlabel(), plt.ylabel() |
设置 X/Y 轴标签文字 | fontsize=12 |
|
plt.xticks(), plt.yticks() |
设置 X/Y 轴的显示刻度步长 | plt.xticks(range(0, 10, 2)) |
|
plt.grid() |
显示背景参考网格线 | linestyle='--', alpha=0.5 |
|
plt.legend() |
渲染各数据系列的图例 | loc='upper right' |
|
| 经典图表 | plt.plot(x, y) |
折线图 :展示随时间/维度的趋势变化 | color, linewidth, marker |
plt.bar(x, height) |
柱状图 :突出不同组别的数量对比 | width, alpha |
|
plt.pie(x) |
饼状图 :展示多部门/类别的比例构成 | autopct='%1.1f%%', labels |