用 Matplotlib 实现数据可视化3 个案例实战

用 Matplotlib 实现数据可视化实战:3 个案例

在数据驱动决策的时代,数据可视化是将枯燥数字转化为直观洞察的核心工具。Matplotlib 作为 Python 生态中最经典的绘图库,能灵活应对各类场景的可视化需求 ------ 无论是反映民生的消费支出分析、保障粮食安全的产量统计,还是助力教育质量提升的成绩对比,都能通过几行代码实现专业级图表。

本文将通过 3 个实战案例(民生消费饼图、粮食产量饼图 + 表格、学生成绩柱形图),带大家从零到一掌握 Matplotlib 的核心用法,每个案例均包含「需求分析→数据准备→代码实现→结果解读」,确保初学者也能跟着动手实践。

案例 1:2023 年全国居民人均消费支出饼图

需求分析

需要将居民消费支出按「食品烟酒、衣着、居住」等 8 类拆分,用饼图展示各类支出的占比,要求:

  • 以消费分类为扇区标签,支出金额为数据依据
  • 为每个扇区指定专属颜色,增强区分度
  • 显示各分类的占比百分比(保留 1 位小数)

数据准备

从官方统计数据中提取 2023 年全国居民人均消费支出明细:

消费分类 支出金额(元)
食品烟酒 7983
衣着 1479
居住 6095
生活用品及服务 1526
交通通信 3652
教育文化娱乐 2904
医疗保健 2460
其他用品及服务 697

代码实现(带详细注释)

python 复制代码
# 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()

结果解读

从饼图可直观看出:

  1. 食品烟酒 (29.8%)和居住(22.7%)是居民最主要的两项支出,合计占比超 50%,反映 "吃" 和 "住" 仍是民生消费的核心;
  2. 交通通信(13.6%)、教育文化娱乐(10.8%)紧随其后,体现居民对出行便利和精神消费的需求提升;
  3. 其他用品及服务(2.6%)占比最低,属于非必需消费。

案例 2:2023 年各品种粮食产量(饼图 + 表格)

需求分析

在展示玉米、大豆等 5 类粮食产量占比的基础上,需额外在饼图下方添加表格显示具体产量,要求:

  • 饼图扇区中心显示占比(保留 1 位小数)
  • 表格需清晰罗列 "品种名称 - 产量(亿斤)" 对应关系
  • 饼图与表格布局协调,不重叠

数据准备

2023 年我国主要粮食品种产量数据(来源:农业农村部统计):

粮食品种 产量(亿斤)
玉米 5776.8
大豆 416.8
薯类 602.8
稻谷 4132.1
小麦 2731.8

代码实现(带详细注释)

python 复制代码
# 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()

结果解读

  1. 产量主导地位:玉米(47.4%)和稻谷(34.0%)是我国最主要的粮食品种,合计占比超 80%,是保障粮食安全的核心;
  2. 小众品种补充:大豆(3.4%)和薯类(4.9%)占比偏低,反映我国需持续推进大豆产能提升行动;
  3. 表格价值:下方表格补充了具体产量数值,既保留饼图的 "占比直观性",又满足用户对 "精确数据" 的需求。

案例 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

代码实现(带详细注释)

python 复制代码
# 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()

结果解读

  1. 性别差异:除高二 2 班外,其余 5 个班女生英语成绩均高于男生,尤其高二 1 班(女生 92.7 分 vs 男生 90.5 分)和高二 6 班(女生 99.8 分 vs 男生 86.6 分)差距明显,需关注男生英语学习薄弱点;
  2. 班级整体水平:高二 1 班、3 班男女成绩均高于年级平均分(88.5 分),整体表现优秀;高二 4 班、5 班需加强提升;
  3. 参考线价值:年级平均分虚线清晰划分 "达标" 与 "待提升" 班级,为教学管理提供明确依据。

总结:Matplotlib 核心知识点回顾

通过 3 个案例,我们掌握了 Matplotlib 的高频用法:

  1. 基础配置plt.rcParams解决中文乱码,figsize控制图表大小;

  2. 图表类型

    • 饼图(pie):适合展示 "占比",autopct显示百分比,explode突出重点;
    • 柱形图(bar):适合 "对比",通过x ± width/2避免两组柱形重叠;
    • 表格(table):搭配图表补充精确数据,bbox调整位置;
  3. 细节优化axhline添加参考线,legend设置图例位置,autolabel添加数值标签,tight_layout避免文字截断。

这些知识点可灵活迁移到其他场景(如销售数据对比、用户行为分析等),大家只需替换数据和调整参数,就能快速生成专业可视化图表!

相关推荐
HashTang3 小时前
2025年10月实时最新获取地图边界数据方法,省市区县街道多级联动【文末附实时geoJson数据下载】
信息可视化·echarts·geojson·乡镇geojson·街道边界·geomap·街道geo
计算机毕业设计木哥13 小时前
计算机毕设选题推荐:基于Hadoop和Python的游戏销售大数据可视化分析系统
大数据·开发语言·hadoop·python·信息可视化·spark·课程设计
std787917 小时前
深入浅出MATLAB数据可视化:超越plot()
matlab·信息可视化·数据分析
啦工作呢17 小时前
数据可视化 ECharts
前端·信息可视化·echarts
揭开画皮17 小时前
5.数据分析Matplotlib(数据可视化)
信息可视化·数据挖掘·数据分析
weixin_4462608518 小时前
轻松可视化数据的利器——JSON Crack
信息可视化·json
嵌入式-老费1 天前
Easyx图形库应用(和Server程序进行交互)
信息可视化
Guheyunyi1 天前
消防管理系统如何重构现代空间防御体系
大数据·运维·人工智能·安全·信息可视化·重构
OG one.Z2 天前
08_Matplotlib数据可视化
信息可视化·matplotlib