一、Matplotlib简介
1.1 什么是Matplotlib
Matplotlib是Python中最常用的数据分析可视化库,可快速绘制各类静态、高质量的图表(如折线图、柱状图、散点图、直方图等),支持自定义图表样式、标签、颜色等细节,是数据分析中“数据呈现”的核心工具。
Matplotlib与NumPy、Pandas的关系:
Matplotlib可直接接收NumPy数组和Pandas的Series、DataFrame数据,无需额外数据格式转换;
Pandas的绘图功能(如df.plot())底层就是基于Matplotlib实现的,可快速生成基础图表;
三者协同使用,可完成“数据读取(Pandas)→ 数据处理(NumPy+Pandas)→ 数据可视化(Matplotlib)”的完整数据分析流程。
核心模块:matplotlib.pyplot(通常简写为plt),是绘制图表的主要接口,提供了简洁的函数式绘图方法。
1.2 安装Matplotlib
使用pip命令安装,与NumPy、Pandas兼容,建议安装最新稳定版:
1 2 3 4 5
| pip install matplotlib
pip install matplotlib==3.7.1
|
验证安装是否成功:
1 2 3 4 5 6
| import matplotlib.pyplot as plt print(plt.__version__)
plt.plot([1, 2, 3, 4]) plt.show()
|
二、Matplotlib绘图基础
2.1 核心绘图流程
Matplotlib绘图遵循“创建画布→绘制图表→设置样式→显示/保存图表”的固定流程,无论绘制哪种图表,核心逻辑一致,流程如下:
导入模块:import matplotlib.pyplot as plt(固定简写);
创建画布(可选):plt.figure(),用于控制画布大小、分辨率等;
绘制图表:调用plt.plot()、plt.bar()等函数,传入数据;
设置样式:添加标题、坐标轴标签、图例、网格等;
显示/保存图表:plt.show()(显示图表)、plt.savefig()(保存图表)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import matplotlib.pyplot as plt import numpy as np
x = np.arange(1, 6) y = x ** 2
plt.figure(figsize=(8, 5), dpi=100)
plt.plot(x, y)
plt.title("简单折线图") plt.xlabel("X轴") plt.ylabel("Y轴") plt.grid(True, linestyle="--", alpha=0.5)
plt.show()
|
2.2 核心概念:画布与子图
在复杂可视化场景中,常需要在一个画布上绘制多个图表(子图),核心函数:plt.subplot() 或 plt.subplots()。
2.2.1 plt.subplot():单个子图创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import matplotlib.pyplot as plt import numpy as np
x = np.arange(1, 6) y1 = x ** 2 y2 = x ** 3
plt.figure(figsize=(10, 4))
plt.subplot(2, 1, 1) plt.plot(x, y1, color="red", label="y=x²") plt.title("y=x² 折线图") plt.legend()
plt.subplot(2, 1, 2) plt.plot(x, y2, color="blue", label="y=x³") plt.title("y=x³ 折线图") plt.legend()
plt.tight_layout()
plt.show()
|
2.2.2 plt.subplots():批量创建子图(推荐)
plt.subplots()会返回“画布对象(figure)”和“子图数组(axes)”,可通过索引直接操作子图,更适合批量处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import matplotlib.pyplot as plt import numpy as np
x = np.arange(1, 6) y1 = x ** 2 y2 = x ** 3 y3 = np.sin(x) y4 = np.cos(x)
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
axes[0, 0].plot(x, y1, color="red") axes[0, 0].set_title("y=x²") axes[0, 0].set_xlabel("X轴") axes[0, 0].grid(True)
axes[0, 1].plot(x, y2, color="blue") axes[0, 1].set_title("y=x³")
axes[1, 0].plot(x, y3, color="green") axes[1, 0].set_title("y=sin(x)")
axes[1, 1].plot(x, y4, color="orange") axes[1, 1].set_title("y=cos(x)")
plt.tight_layout() plt.show()
|
2.3 常用样式设置
图表样式直接影响可读性,重点掌握以下常用设置,可让图表更规范、美观:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| import matplotlib.pyplot as plt import numpy as np
x = np.arange(1, 6) y = x ** 2
plt.figure(figsize=(8, 5))
plt.plot(x, y, color="purple", linestyle="-.", linewidth=2, marker="o", markersize=8, markerfacecolor="white")
plt.title("样式设置示例", fontsize=14, fontweight="bold") plt.xlabel("X轴(单位:个)", fontsize=12) plt.ylabel("Y轴(单位:平方)", fontsize=12)
plt.xlim(0, 6) plt.ylim(0, 30)
plt.legend(loc="upper left", fontsize=10)
plt.grid(True, linestyle="--", alpha=0.3)
plt.xticks([0, 2, 4, 6], labels=["0", "2", "4", "6"]) plt.yticks([0, 10, 20, 30])
plt.show()
|
三、Matplotlib常见图表绘制(核心实战)
结合数据分析场景,重点掌握以下6类常见图表,覆盖80%的可视化需求,所有示例均兼容NumPy数组和Pandas数据。
3.1 折线图(plot)
用途:展示数据随时间/连续变量的变化趋势(如销量变化、气温变化)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import matplotlib.pyplot as plt import pandas as pd
data = { "月份": [1, 2, 3, 4, 5, 6], "销量": [120, 150, 130, 180, 160, 200], "利润": [20, 25, 22, 30, 28, 35] } df = pd.DataFrame(data)
plt.figure(figsize=(8, 5))
plt.plot(df["月份"], df["销量"], label="销量", color="blue", marker="o") plt.plot(df["月份"], df["利润"], label="利润", color="red", marker="s")
plt.title("月度销量与利润变化趋势", fontsize=14) plt.xlabel("月份", fontsize=12) plt.ylabel("金额(万元)", fontsize=12) plt.legend() plt.grid(True, alpha=0.3) plt.xticks(df["月份"])
plt.show()
|
3.2 柱状图(bar/barh)
用途:对比多个类别数据的差异(如不同产品销量、不同班级平均分),分为垂直柱状图(bar)和水平柱状图(barh)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| import matplotlib.pyplot as plt import pandas as pd
df = pd.DataFrame({ "产品": ["A", "B", "C", "D"], "销量": [350, 280, 420, 300] })
plt.figure(figsize=(8, 5))
plt.bar(df["产品"], df["销量"], color=["red", "blue", "green", "orange"], width=0.6, edgecolor="black")
for i, v in enumerate(df["销量"]): plt.text(i, v + 10, str(v), ha="center", fontsize=10)
plt.title("不同产品销量对比", fontsize=14) plt.xlabel("产品", fontsize=12) plt.ylabel("销量(件)", fontsize=12) plt.ylim(0, 450)
plt.show()
|
3.3 散点图(scatter)
用途:展示两个变量之间的相关性(如身高与体重、学习时间与成绩),点的颜色/大小可映射第三个变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import matplotlib.pyplot as plt import numpy as np
np.random.seed(1) study_time = np.random.randint(1, 10, 50) score = 60 + study_time * 3 + np.random.randn(50) * 2
plt.figure(figsize=(8, 5))
scatter = plt.scatter(study_time, score, c=score, cmap="RdYlGn", s=50, alpha=0.7)
plt.colorbar(scatter, label="成绩")
plt.title("学习时间与成绩相关性", fontsize=14) plt.xlabel("学习时间(小时)", fontsize=12) plt.ylabel("成绩(分)", fontsize=12) plt.grid(True, alpha=0.3)
plt.show()
|
3.4 直方图(hist)
用途:展示数据的分布情况(如成绩分布、身高分布),将数据分组,统计每组的频数/频率。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import matplotlib.pyplot as plt import numpy as np
scores = np.random.normal(80, 5, 500)
plt.figure(figsize=(8, 5))
plt.hist(scores, bins=15, color="lightblue", edgecolor="black", alpha=0.7)
plt.title("500名学生成绩分布", fontsize=14) plt.xlabel("成绩(分)", fontsize=12) plt.ylabel("学生人数", fontsize=12) plt.grid(True, alpha=0.3, axis="y")
plt.axvline(scores.mean(), color="red", linestyle="--", label=f"均值:{scores.mean():.1f}") plt.legend()
plt.show()
|
3.5 饼图(pie)
用途:展示各部分占总体的比例(如各产品销量占比、各科目成绩占比),注意:数据总和需为100%或可归一化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import matplotlib.pyplot as plt import pandas as pd
df = pd.DataFrame({ "产品": ["A", "B", "C", "D"], "销量": [350, 280, 420, 300] })
df["占比"] = df["销量"] / df["销量"].sum() * 100
plt.figure(figsize=(7, 7))
plt.pie(df["销量"], labels=df["产品"], autopct="%1.1f%%", colors=["red", "blue", "green", "orange"], explode=[0.05, 0, 0.05, 0], shadow=True, startangle=90)
plt.title("各产品销量占比", fontsize=14) plt.axis("equal")
plt.show()
|
3.6 箱线图(boxplot)
用途:展示数据的分布特征(中位数、四分位数、异常值),常用于异常值检测(如成绩中的极端值、销量中的异常数据)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import matplotlib.pyplot as plt import numpy as np
class1 = np.random.normal(80, 5, 50) class2 = np.random.normal(75, 8, 50) class3 = np.random.normal(85, 6, 50) data = [class1, class2, class3]
plt.figure(figsize=(8, 5))
box = plt.boxplot(data, labels=["一班", "二班", "三班"], patch_artist=True, boxprops={"facecolor": "lightblue"}, flierprops={"color": "red", "marker": "o"})
plt.title("3个班级成绩分布箱线图", fontsize=14) plt.xlabel("班级", fontsize=12) plt.ylabel("成绩(分)", fontsize=12) plt.grid(True, alpha=0.3, axis="y")
plt.show()
|
四、Matplotlib与Pandas结合实战
Pandas的DataFrame自带plot()方法,可快速调用Matplotlib绘制图表,语法更简洁,适合快速可视化,底层仍依赖Matplotlib,可结合Matplotlib的样式设置优化图表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| import matplotlib.pyplot as plt import pandas as pd import numpy as np
df = pd.DataFrame({ "姓名": ["张三", "李四", "王五", "赵六", "孙七", "周八"], "班级": ["一班", "一班", "二班", "二班", "一班", "二班"], "成绩": [85, 92, 78, 90, 88, 82], "年龄": [20, 21, 19, 22, 20, 19] })
plt.figure(figsize=(8, 5)) class_score = df.groupby("班级")["成绩"].mean() class_score.plot(kind="line", marker="o", color="blue")
plt.title("各班级平均成绩", fontsize=14) plt.xlabel("班级", fontsize=12) plt.ylabel("平均分", fontsize=12) plt.legend() plt.grid(True, alpha=0.3) plt.show()
plt.figure(figsize=(8, 5)) class_count = df.groupby("班级")["姓名"].count() class_count.plot(kind="bar", color=["red", "blue"])
for i, v in enumerate(class_count): plt.text(i, v + 0.1, str(v), ha="center")
plt.title("各班级人数统计", fontsize=14) plt.xlabel("班级", fontsize=12) plt.ylabel("人数", fontsize=12) plt.ylim(0, 4) plt.show()
plt.figure(figsize=(8, 5)) df.plot(kind="scatter", x="年龄", y="成绩", c="成绩", cmap="RdYlGn", s=50, alpha=0.7)
plt.title("年龄与成绩相关性", fontsize=14) plt.grid(True, alpha=0.3) plt.colorbar(label="成绩") plt.show()
|
五、常见问题与注意事项
中文显示问题:默认情况下,Matplotlib不支持中文,会显示乱码,解决方案:添加字体设置(plt.rcParams)。
\# 解决中文乱码(放在导入模块后、绘图前) plt\.rcParams\[\&\#34;font\.sans\-serif\&\#34;\] = \[\&\#34;SimHei\&\#34;\] \# 中文支持(Windows系统) plt\.rcParams\[\&\#34;axes\.unicode\_minus\&\#34;\] = False \# 解决负号显示异常
图表保存问题:plt.savefig()必须放在plt.show()之前,否则会保存为空(plt.show()会清空画布);若标签被截断,添加bbox_inches="tight"参数。
子图间距问题:多个子图叠加时,标题、标签可能重叠,使用plt.tight_layout()自动调整子图间距,或用plt.subplots_adjust()手动调整。
数据格式问题:Matplotlib优先接收NumPy数组和Pandas的Series、DataFrame,若传入Python列表,会自动转换,但效率较低,建议提前转换为NumPy数组。
样式一致性:同一批图表(如同一分析报告中的图表),需保持颜色、字体、线型的一致性,提升专业性。
图表可读性:避免过度装饰,重点突出数据;添加必要的标题、标签、图例,让读者快速理解图表含义;数值标签需清晰,避免重叠。
六、总结
Matplotlib是Python数据分析可视化的核心工具,重点掌握以下内容,即可满足大部分数据分析场景的可视化需求:
绘图基础:核心流程(创建画布→绘制图表→设置样式→显示/保存)、画布与子图的使用;
常见图表:折线图(趋势)、柱状图(对比)、散点图(相关性)、直方图(分布)、饼图(占比)、箱线图(异常值);
样式设置:标题、坐标轴、图例、网格、颜色、线型等细节优化;
协同使用:与NumPy、Pandas结合,实现数据处理与可视化的无缝衔接;
实战技巧:中文显示、图表保存、子图间距调整、数值标签添加等。
Matplotlib的功能十分强大,除了基础图表,还可绘制3D图表、动态图表等,后续可结合具体业务场景深入学习;同时,可了解Seaborn库(基于Matplotlib),其封装了更简洁的API,可快速绘制更美观的统计图表。