Matplotlib是Python生态中最核心的数据可视化库之一,凭借灵活的定制能力和简洁的语法,成为数据分析、科研绘图、报表制作的必备工具。本文将从实战角度出发,手把手教你掌握折线图、柱状图、直方图三种高频图表的绘制方法,覆盖基础语法、参数调整、样式优化等核心知识点,零基础也能快速上手。
一、前期准备:环境搭建与基础概念
1. 安装Matplotlib
确保已安装Python环境,通过pip命令快速安装Matplotlib:
pip install matplotlib同时建议安装NumPy,用于生成示例数据:
pip install numpy2. 核心模块与绘图逻辑
Matplotlib的绘图核心是pyplot模块,通常简写为plt。其基本绘图逻辑为:
- 导入模块:
import matplotlib.pyplot as plt - 准备数据:整理需要可视化的数值型数据
- 调用绘图函数(如
plot()、bar()):生成图表框架 - 调整样式(标题、标签、刻度等):提升图表可读性
- 显示/保存图表:
plt.show()或plt.savefig()
二、折线图:展示数据趋势变化
折线图适用于展示数据随时间、序列等维度的连续变化趋势,是最常用的趋势可视化图表。
1. 基础折线图绘制
示例:绘制某城市一周的气温变化趋势
importmatplotlib.pyplotaspltimportnumpyasnp# 1. 准备数据x=["周一","周二","周三","周四","周五","周六","周日"]# 横轴:星期y=[22,24,21,26,28,27,25]# 纵轴:气温(℃)# 2. 创建画布(可选,默认自动创建)plt.figure(figsize=(8,5))# 设置画布大小:宽8英寸,高5英寸# 3. 绘制折线图plt.plot(x,y,# x/y轴数据color="red",# 线条颜色linestyle="-",# 线条样式:实线(--为虚线,:为点线)linewidth=2,# 线条宽度marker="o",# 数据点标记:圆形(s为正方形,^为三角形)markersize=6)# 标记大小# 4. 添加图表元素plt.title("某城市一周气温变化趋势",fontsize=14)# 标题plt.xlabel("星期",fontsize=12)# 横轴标签plt.ylabel("气温(℃)",fontsize=12)plt.xticks(fontsize=10)# 横轴刻度字体大小plt.yticks(range(20,30,2),fontsize=10)# 纵轴刻度范围与步长plt.grid(alpha=0.3)# 添加网格,alpha控制透明度# 5. 显示图表plt.show()2. 进阶:多折线对比
若需对比多组数据趋势(如最高温与最低温),多次调用plot()即可:
importmatplotlib.pyplotasplt# 数据准备x=["周一","周二","周三","周四","周五","周六","周日"]high_temp=[22,24,21,26,28,27,25]low_temp=[15,16,14,18,20,19,17]plt.figure(figsize=(8,5))# 绘制最高温折线plt.plot(x,high_temp,color="red",marker="o",label="最高温")# 绘制最低温折线plt.plot(x,low_temp,color="blue",marker="s",label="最低温")# 添加图例(需配合label参数)plt.legend(loc="upper right",fontsize=10)plt.title("某城市一周最高/最低气温对比",fontsize=14)plt.xlabel("星期")plt.ylabel("气温(℃)")plt.grid(alpha=0.3)plt.show()三、柱状图:对比不同类别数据大小
柱状图(条形图)适用于对比不同类别、分组数据的数值大小,直观展示各类别间的差异。
1. 基础柱状图绘制
示例:对比不同产品的月度销量
importmatplotlib.pyplotasplt# 数据准备products=["产品A","产品B","产品C","产品D"]sales=[120,180,90,150]# 销量(件)plt.figure(figsize=(8,5))# 绘制柱状图bars=plt.bar(products,sales,width=0.6,# 柱子宽度color=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4"],# 自定义颜色edgecolor="black")# 柱子边框颜色# 为柱子添加数值标签forbarinbars:height=bar.get_height()plt.text(bar.get_x()+bar.get_width()/2,# 标签x坐标(柱子中心)height+2,# 标签y坐标(柱子顶部+偏移)str(height),# 标签内容ha="center",fontsize=10)# 水平居中plt.title("月度产品销量对比",fontsize=14)plt.xlabel("产品类别")plt.ylabel("销量(件)")plt.ylim(0,200)# 纵轴范围,避免标签超出图表plt.show()2. 进阶:分组柱状图
若需对比同一类别在不同维度的数据(如2023和2024年各产品销量),可绘制分组柱状图:
importmatplotlib.pyplotaspltimportnumpyasnp# 数据准备products=["产品A","产品B","产品C","产品D"]sales_2023=[120,180,90,150]sales_2024=[150,160,110,170]x=np.arange(len(products))# 生成x轴位置:[0,1,2,3]width=0.35# 每组柱子宽度plt.figure(figsize=(8,5))# 绘制2023年销量柱子plt.bar(x-width/2,sales_2023,width,label="2023年",color="#FF6B6B")# 绘制2024年销量柱子plt.bar(x+width/2,sales_2024,width,label="2024年",color="#4ECDC4")# 调整x轴刻度与标签plt.xticks(x,products)plt.legend(fontsize=10)plt.title("2023-2024年产品销量对比",fontsize=14)plt.xlabel("产品类别")plt.ylabel("销量(件)")plt.show()四、直方图:展示数据分布特征
直方图与柱状图易混淆,但核心用途不同:直方图用于展示连续数据的分布情况(如身高、分数、销售额的分布),横轴为数据区间,纵轴为区间内的频数/频率。
1. 基础直方图绘制
示例:分析1000名学生的数学成绩分布
importmatplotlib.pyplotaspltimportnumpyasnp# 生成模拟数据:均值75,标准差10的正态分布成绩np.random.seed(42)# 固定随机种子,保证结果可复现scores=np.random.normal(75,10,1000)scores=np.clip(scores,0,100)# 限制成绩范围0-100plt.figure(figsize=(8,5))# 绘制直方图n,bins,patches=plt.hist(scores,bins=10,# 区间数量(组数)range=(0,100),# 数据范围color="#45B7D1",edgecolor="black",alpha=0.7)# 添加数值标签foriinrange(len(n)):plt.text((bins[i]+bins[i+1])/2,# 区间中心x坐标n[i]+5,# 频数y坐标+偏移int(n[i]),# 频数(取整)ha="center",fontsize=9)plt.title("1000名学生数学成绩分布",fontsize=14)plt.xlabel("成绩区间")plt.ylabel("人数(频数)")plt.grid(axis="y",alpha=0.3)# 仅显示y轴网格plt.show()2. 关键参数说明
bins:组数,可指定具体区间(如bins=[0,60,70,80,90,100]),也可指定数量;density:若设为True,纵轴显示频率(概率密度)而非频数;range:限定数据范围,超出范围的数据会被忽略。
五、通用优化技巧
- 中文显示问题:若图表中中文乱码,添加以下代码:
plt.rcParams["font.sans-serif"]=["SimHei"]# Windows系统# plt.rcParams["font.sans-serif"] = ["PingFang SC"] # macOS系统plt.rcParams["axes.unicode_minus"]=False# 解决负号显示问题- 保存图表:用
plt.savefig()替代plt.show(),可保存高清图片:
plt.savefig("气温趋势.png",dpi=300,bbox_inches="tight")# dpi控制分辨率,bbox_inches裁剪空白- 样式预设:Matplotlib提供多种预设样式,可通过
plt.style.use()调用:
plt.style.use("ggplot")# 仿R语言ggplot2样式plt.style.use("seaborn-v0_8")# 仿seaborn样式