用 Matplotlib 实现数据可视化3 个案例实战
用 Matplotlib 实现数据可视化实战:3 个案例
在数据驱动决策的时代,数据可视化是将枯燥数字转化为直观洞察的核心工具。Matplotlib 作为 Python 生态中最经典的绘图库,能灵活应对各类场景的可视化需求 —— 无论是反映民生的消费支出分析、保障粮食安全的产量统计,还是助力教育质量提升的成绩对比,都能通过几行代码实现专业级图表。
本文将通过 3 个实战案例(民生消费饼图、粮食产量饼图 + 表格、学生成绩柱形图),带大家从零到一掌握 Matplotlib 的核心用法,每个案例均包含「需求分析→数据准备→代码实现→结果解读」,确保初学者也能跟着动手实践。
案例 1:2023 年全国居民人均消费支出饼图
需求分析
需要将居民消费支出按「食品烟酒、衣着、居住」等 8 类拆分,用饼图展示各类支出的占比,要求:
- 以消费分类为扇区标签,支出金额为数据依据
- 为每个扇区指定专属颜色,增强区分度
- 显示各分类的占比百分比(保留 1 位小数)
数据准备
从官方统计数据中提取 2023 年全国居民人均消费支出明细:
消费分类 | 支出金额(元) |
---|---|
食品烟酒 | 7983 |
衣着 | 1479 |
居住 | 6095 |
生活用品及服务 | 1526 |
交通通信 | 3652 |
教育文化娱乐 | 2904 |
医疗保健 | 2460 |
其他用品及服务 | 697 |
代码实现(带详细注释)
# 1. 导入必备库
import matplotlib.pyplot as plt
import numpy as np# 2. 解决中文显示乱码(Matplotlib默认不支持中文,这步必加)
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans'] # 支持中文+英文
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示异常问题# 3. 准备数据(与上述表格一一对应)
kinds = ['食品烟酒', '衣着', '居住', '生活用品及服务', '交通通信', '教育文化娱乐', '医疗保健', '其他用品及服务']
money_scale = np.array([7983, 1479, 6095, 1526, 3652, 2904, 2460, 697])# 4. 定义扇区颜色(选色原则:对比鲜明、视觉舒适,可自定义)
colors = ['#E64A19', '#3949AB', '#4CAF50', '#FFC107', '#2196F3', '#9C27B0', '#00BCD4', '#795548']# 5. 创建饼图
fig, ax = plt.subplots(figsize=(10, 8)) # 设置图表大小(宽10英寸,高8英寸)# 核心参数解释:
# explode:让占比最高的2类(食品烟酒、居住)向外突出5%,增强视觉重点
# autopct:指定百分比格式(%1.1f%% 表示保留1位小数)
explode = (0.05, 0, 0.05, 0, 0, 0, 0, 0)
wedges, texts, autotexts = ax.pie(x=money_scale, # 饼图数据(支出金额)labels=kinds, # 扇区标签(消费分类)colors=colors, # 扇区颜色autopct='%1.1f%%', # 显示百分比startangle=90, # 起始角度(从正上方开始顺时针绘制)textprops={'fontsize': 11} # 标签文字大小
)# 6. 调整布局+显示/保存图表
plt.title('2023年全国居民人均消费支出及其构成', fontsize=14, fontweight='bold', pad=20)
plt.tight_layout() # 自动调整布局,避免文字被截断
# plt.savefig('居民消费支出饼图.png', dpi=300, bbox_inches='tight') # 可选:保存为高清图片
plt.show()
结果解读
从饼图可直观看出:
- 食品烟酒(29.8%)和居住(22.7%)是居民最主要的两项支出,合计占比超 50%,反映 “吃” 和 “住” 仍是民生消费的核心;
- 交通通信(13.6%)、教育文化娱乐(10.8%)紧随其后,体现居民对出行便利和精神消费的需求提升;
- 其他用品及服务(2.6%)占比最低,属于非必需消费。
案例 2:2023 年各品种粮食产量(饼图 + 表格)
需求分析
在展示玉米、大豆等 5 类粮食产量占比的基础上,需额外在饼图下方添加表格显示具体产量,要求:
- 饼图扇区中心显示占比(保留 1 位小数)
- 表格需清晰罗列 “品种名称 - 产量(亿斤)” 对应关系
- 饼图与表格布局协调,不重叠
数据准备
2023 年我国主要粮食品种产量数据(来源:农业农村部统计):
粮食品种 | 产量(亿斤) |
---|---|
玉米 | 5776.8 |
大豆 | 416.8 |
薯类 | 602.8 |
稻谷 | 4132.1 |
小麦 | 2731.8 |
代码实现(带详细注释)
# 1. 导入库
import matplotlib.pyplot as plt
import numpy as np# 2. 解决中文乱码
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False# 3. 准备数据
category_name = np.array(['玉米', '大豆', '薯类', '稻谷', '小麦']) # 品种名称
yield_data = np.array([5776.8, 416.8, 602.8, 4132.1, 2731.8]) # 产量(亿斤)
total_yield = yield_data.sum() # 总产量(用于计算占比)
percentages = (yield_data / total_yield) * 100 # 各品种占比(%)# 4. 定义饼图颜色(对应5类粮食,视觉区分明显)
colors = ['#4169E1', '#FFA500', '#32CD32', '#CD5C5C', '#9370DB']# 5. 创建画布:分2行1列(上:饼图,下:表格),高度比例2:1
fig, (ax_pie, ax_table) = plt.subplots(2, 1, figsize=(8, 6), gridspec_kw={'height_ratios': [2, 1]} # 控制上下区域高度
)# 6. 绘制饼图
ax_pie.pie(percentages,labels=category_name,colors=colors,autopct='%1.1f%%', # 扇区中心显示占比(1位小数)startangle=0, # 从水平方向开始绘制textprops={'fontsize': 10}
)
ax_pie.axis('equal') # 保证饼图是正圆形(避免拉伸成椭圆)
ax_pie.set_title('2023年各品种粮食产量占比', fontsize=12, fontweight='bold', pad=15)# 7. 绘制下方表格(隐藏坐标轴,避免干扰)
ax_table.axis('off') # 关闭表格区域的坐标轴
table = ax_pie.table(cellText=[yield_data], # 表格数据(1行5列,对应5个品种的产量)cellLoc='center', # 单元格文字居中colWidths=[0.12]*5, # 5列,每列宽度0.12(总宽度适配饼图)rowLabels=['产量(亿斤)'],# 行标签(说明数据单位)rowLoc='center', # 行标签居中colLabels=category_name,# 列标签(品种名称)colLoc='center', # 列标签居中loc='lower center', # 表格位置(饼图正下方)bbox=[0, -0.3, 1, 0.2] # 调整表格位置和大小(左、下、宽、高)
)# 8. 调整布局并显示
plt.tight_layout()
plt.show()
结果解读
- 产量主导地位:玉米(47.4%)和稻谷(34.0%)是我国最主要的粮食品种,合计占比超 80%,是保障粮食安全的核心;
- 小众品种补充:大豆(3.4%)和薯类(4.9%)占比偏低,反映我国需持续推进大豆产能提升行动;
- 表格价值:下方表格补充了具体产量数值,既保留饼图的 “占比直观性”,又满足用户对 “精确数据” 的需求。
案例 3:高二各班男生、女生英语成绩柱形图
需求分析
对比全校高二年级 6 个班男生和女生的英语平均成绩,需添加年级平均分参考线,要求:
- 两组柱形分别代表 “男生成绩” 和 “女生成绩”,避免重叠
- 水平虚线表示年级平均分(88.5 分),作为成绩对比基准
- 标题、坐标轴标签清晰,图例位于右下角
数据准备
高二年级 6 个班男女英语平均成绩及年级平均分:
班级 | 男生平均成绩 | 女生平均成绩 |
---|---|---|
高二 1 班 | 90.5 | 92.7 |
高二 2 班 | 89.5 | 87.0 |
高二 3 班 | 88.7 | 90.5 |
高二 4 班 | 88.5 | 85.0 |
高二 5 班 | 85.2 | 89.5 |
高二 6 班 | 86.6 | 89.8 |
年级平均 | - | 88.5 |
代码实现(带详细注释)
# 1. 导入库
import matplotlib.pyplot as plt
import numpy as np# 2. 解决中文乱码
plt.rcParams['font.sans-serif'] = ['SimHei', 'WenQuanYi Zen Hei']
plt.rcParams['axes.unicode_minus'] = False# 3. 准备数据
classes = ['高二1班', '高二2班', '高二3班', '高二4班', '高二5班', '高二6班'] # 班级列表
men_means = (90.5, 89.5, 88.7, 88.5, 85.2, 86.6) # 男生成绩
women_means = (92.7, 87.0, 90.5, 85.0, 89.5, 89.8) # 女生成绩
grade_avg = 88.5 # 年级平均分(参考线)# 4. 柱形图基础设置
width = 0.35 # 柱形宽度(控制两组柱形的间距,避免重叠)
x = np.arange(len(classes)) # x轴刻度位置(对应6个班级)
fig, ax = plt.subplots(figsize=(10, 6)) # 图表大小# 5. 绘制两组柱形
# 男生柱形:位置偏左(x - width/2),蓝色,标签“男生平均成绩”
rects1 = ax.bar(x - width/2, men_means, width, label='男生平均成绩', color='#1f77b4')
# 女生柱形:位置偏右(x + width/2),橙色,标签“女生平均成绩”
rects2 = ax.bar(x + width/2, women_means, width, label='女生平均成绩', color='#ff7f0e')# 6. 绘制水平参考线(年级平均分)
ax.axhline(y=grade_avg, color='gray', linestyle='--', # 虚线样式linewidth=1.5, label=f'年级平均成绩({grade_avg}分)' # 参考线标签
)# 7. 设置标题、坐标轴标签和刻度
ax.set_title('高二各班男生、女生英语平均成绩', fontsize=16, fontweight='bold', pad=20)
ax.set_ylabel('分数', fontsize=12, fontweight='bold') # y轴标签(成绩分数)
ax.set_xticks(x) # x轴刻度位置(对齐两组柱形中间)
ax.set_xticklabels(classes, fontsize=11) # x轴刻度标签(班级名称)# 8. 设置图例(位置:右下角,避免遮挡柱形)
ax.legend(loc='lower right', fontsize=11)# 9. (可选)在柱形顶部添加具体分数(方便直接读取数值)
def autolabel(rects):for rect in rects:height = rect.get_height() # 获取柱形高度(即成绩)ax.annotate(f'{height}', # 标签内容(成绩)xy=(rect.get_x() + rect.get_width() / 2, height), # 标签位置(柱形顶部中心)xytext=(0, 3), # 标签向上偏移3个像素(避免与柱形重叠)textcoords="offset points",ha='center', va='bottom', fontsize=9)
autolabel(rects1) # 男生柱形添加分数标签
autolabel(rects2) # 女生柱形添加分数标签# 10. 调整布局并显示
plt.tight_layout()
plt.show()
结果解读
- 性别差异:除高二 2 班外,其余 5 个班女生英语成绩均高于男生,尤其高二 1 班(女生 92.7 分 vs 男生 90.5 分)和高二 6 班(女生 99.8 分 vs 男生 86.6 分)差距明显,需关注男生英语学习薄弱点;
- 班级整体水平:高二 1 班、3 班男女成绩均高于年级平均分(88.5 分),整体表现优秀;高二 4 班、5 班需加强提升;
- 参考线价值:年级平均分虚线清晰划分 “达标” 与 “待提升” 班级,为教学管理提供明确依据。
总结:Matplotlib 核心知识点回顾
通过 3 个案例,我们掌握了 Matplotlib 的高频用法:
-
基础配置:
plt.rcParams
解决中文乱码,figsize
控制图表大小; -
图表类型
:
- 饼图(
pie
):适合展示 “占比”,autopct
显示百分比,explode
突出重点; - 柱形图(
bar
):适合 “对比”,通过x ± width/2
避免两组柱形重叠; - 表格(
table
):搭配图表补充精确数据,bbox
调整位置;
- 饼图(
-
细节优化:
axhline
添加参考线,legend
设置图例位置,autolabel
添加数值标签,tight_layout
避免文字截断。
这些知识点可灵活迁移到其他场景(如销售数据对比、用户行为分析等),大家只需替换数据和调整参数,就能快速生成专业可视化图表!