
文章目录
-
- [一、为什么需要数据可视化?先看 "数字 vs 图表" 的差距](#一、为什么需要数据可视化?先看 “数字 vs 图表” 的差距)
- [二、可视化基础:Matplotlib 入门(基础图表绘制)](#二、可视化基础:Matplotlib 入门(基础图表绘制))
-
- [1. 安装与基础配置](#1. 安装与基础配置)
-
- [▶ 安装 Matplotlib](#▶ 安装 Matplotlib)
- [▶ 基础配置(解决中文字体乱码)](#▶ 基础配置(解决中文字体乱码))
- [2. 核心概念:Matplotlib 的 "图层" 逻辑](#2. 核心概念:Matplotlib 的 “图层” 逻辑)
- [3. 实战 1:柱状图(对比数据大小)](#3. 实战 1:柱状图(对比数据大小))
- [4. 实战 2:饼图(展示数据占比)](#4. 实战 2:饼图(展示数据占比))
- [5. 实战 3:折线图(展示数据趋势)](#5. 实战 3:折线图(展示数据趋势))
- [三、可视化进阶:Seaborn 美化与复杂图表](#三、可视化进阶:Seaborn 美化与复杂图表)
-
- [1. 安装与基础配置](#1. 安装与基础配置)
-
- [▶ 安装 Seaborn](#▶ 安装 Seaborn)
- [▶ 基础配置(启用 Seaborn 样式)](#▶ 基础配置(启用 Seaborn 样式))
- [2. 实战 1:箱线图(展示数据分布与异常值)](#2. 实战 1:箱线图(展示数据分布与异常值))
- [3. 实战 2:热力图(展示变量间的相关性)](#3. 实战 2:热力图(展示变量间的相关性))
- 四、综合实操:学生成绩可视化报告(多图表组合)
- [五、新手必踩的 5 个坑:避坑指南](#五、新手必踩的 5 个坑:避坑指南)
-
- [坑 1:中文字体乱码(最常见)](#坑 1:中文字体乱码(最常见))
- [坑 2:子图布局重叠(标签被截断)](#坑 2:子图布局重叠(标签被截断))
- [坑 3:Seaborn 和 Matplotlib 样式冲突](#坑 3:Seaborn 和 Matplotlib 样式冲突)
- [坑 4:饼图标签拥挤(类别过多)](#坑 4:饼图标签拥挤(类别过多))
- [坑 5:保存图表时标签被截断](#坑 5:保存图表时标签被截断)
- 六、小结与下一篇预告
欢迎回到「Python 从入门到实战」系列专栏。上一篇咱们用 Pandas 搞定了学生成绩的筛选、清洗和统计 ------ 比如算出 "数学平均分 86 分""小红是优秀学生",但这些数字总感觉不够直观:各科成绩差距有多大?成绩等级分布是否均衡?不同学生的总分对比如何?只看数字很难快速 get 到这些信息。
今天咱们要学 Python 数据可视化的 "双王牌"------Matplotlib 和Seaborn。它们就像数据的 "化妆师",能把枯燥的数字变成直观的图表(柱状图、折线图、饼图等),让数据的趋势、分布、对比关系一目了然。咱们会从基础的 "Matplotlib 绘图" 入手,再用 Seaborn 美化图表,最后结合上一篇的学生成绩数据,实战生成 "成绩分析可视化报告",让你的数据分析结果既有深度又有颜值。
一、为什么需要数据可视化?先看 "数字 vs 图表" 的差距
上一篇我们用 Pandas 统计了学生成绩的核心信息,比如:
- 数学平均分 86.0,英语平均分 87.3;
- 成绩等级分布:A 级 2 人,B 级 3 人,C 级 1 人;
- 学生总分:小红 183 分,小明 177 分,小刚 160 分。
这些数字很准确,但不够直观 ------ 比如 "各科平均分差距",你需要手动计算差值(87.3-86.0=1.3)才能知道差距小;而用柱状图展示,一眼就能看出两科分数的高度差异:
| 数字统计 | 柱状图可视化 |
|---|---|
| 数学平均分 86.0,英语平均分 87.3 | ![]() (示意:英语柱略高于数学柱) |
再比如 "成绩等级分布",数字 "A 级 2 人、B 级 3 人、C 级 1 人" 需要在脑子里换算比例;而用饼图展示,各等级的占比一眼就能看清:
| 数字统计 | 饼图可视化 |
|---|---|
| A 级 2 人、B 级 3 人、C 级 1 人 | ![]() (示意:B 级占比最大,约 50%) |
这就是数据可视化的核心价值:将抽象数字转化为直观图形,降低理解成本,快速传递数据洞察。
二、可视化基础:Matplotlib 入门(基础图表绘制)
Matplotlib 是 Python 最核心的可视化库,几乎所有其他可视化库(包括 Seaborn)都基于它开发。它支持绘制折线图、柱状图、饼图等多种图表,灵活性极高。咱们先从 "安装" 和 "基础配置" 入手,再实战绘制常用图表。
1. 安装与基础配置
▶ 安装 Matplotlib
打开终端 / 命令提示符,输入以下命令安装:
bash
bash
pip install matplotlib
▶ 基础配置(解决中文字体乱码)
Matplotlib 默认不支持中文字体,直接绘图会出现 "方框乱码",需要提前配置。在代码开头添加以下配置(复制即用):
python
python
import matplotlib.pyplot as plt
import pandas as pd
# 解决中文字体乱码(Windows用SimHei,macOS用PingFang SC)
plt.rcParams['font.sans-serif'] = ['SimHei', 'PingFang SC'] # 中文支持
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
2. 核心概念:Matplotlib 的 "图层" 逻辑
Matplotlib 绘图像 "叠报纸",有三个核心图层,理解它们才能灵活调整图表:
- Figure(画布):最外层的 "大画板",所有图表都在画布上绘制;
- Axes(子图):画布上的 "小画板",一个画布可以有多个子图(比如一行两列的子图);
- 元素(标签、标题、图例):绘制在 Axes 上的细节,比如轴标签、图表标题、图例等。
简单来说:先创建 "画布(Figure)",再在画布上划分 "子图(Axes)",最后在子图上添加 "元素"。
3. 实战 1:柱状图(对比数据大小)
柱状图适合 "对比不同类别数据的大小",比如各科平均分、各学生总分。
示例:用柱状图展示 "各科平均分"
用上一篇的学生成绩数据,先通过 Pandas 计算各科平均分,再用 Matplotlib 绘制柱状图:
python
python
import matplotlib.pyplot as plt
import pandas as pd
# 1. 配置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'PingFang SC']
plt.rcParams['axes.unicode_minus'] = False
# 2. 读取数据(上一篇的学生成绩数据)
df = pd.read_csv("students_data.csv", encoding="utf-8", dtype={"course_score": int})
# 3. 用Pandas计算各科平均分
course_avg = df.groupby("course_name")["course_score"].mean().round(1)
print("各科平均分:")
print(course_avg)
# 4. 绘制柱状图
# 创建画布(figsize:宽8英寸,高5英寸;dpi:分辨率)
fig, ax = plt.subplots(figsize=(8, 5), dpi=100)
# 绘制柱状图(x=课程名,y=平均分,颜色=蓝色,边框=黑色)
bars = ax.bar(
x=course_avg.index, # x轴:课程名
height=course_avg.values, # y轴:平均分
color='skyblue', # 柱体颜色
edgecolor='black' # 柱体边框颜色
)
# 5. 添加图表元素(标题、轴标签、数值标签)
ax.set_title("学生各科平均分对比", fontsize=14, pad=20) # 标题(字号14,距离轴20像素)
ax.set_xlabel("课程名称", fontsize=12) # x轴标签
ax.set_ylabel("平均分(分)", fontsize=12) # y轴标签
# 在每个柱子顶部添加数值标签
for bar in bars:
height = bar.get_height() # 获取柱子高度(即平均分)
ax.text(
bar.get_x() + bar.get_width()/2, # x坐标:柱子中心
height + 0.5, # y坐标:柱子顶部+0.5(避免和柱子重叠)
str(height), # 显示的数值
ha='center', va='bottom', fontsize=11 # 水平居中、垂直靠下
)
# 6. 调整y轴范围(让图表更美观)
ax.set_ylim(80, 90) # y轴从80到90,突出差距
# 7. 保存图表(bbox_inches='tight':避免标签被截断)
plt.savefig("course_avg_bar.png", bbox_inches='tight')
# 显示图表(Jupyter Notebook中需加plt.show())
plt.show()
运行结果
-
控制台输出:
plaintext
plaintext各科平均分: course_name 数学 86.0 英语 87.3 Name: course_score, dtype: float64 -
生成的图表 :
course_avg_bar.png(蓝色柱状图,数学柱高 86.0,英语柱高 87.3,顶部有数值标签,标题和轴标签清晰)。
柱状图适用场景
- 对比不同类别的数据(如各科成绩、各部门销售额);
- 展示单一指标在不同维度的大小差异。
4. 实战 2:饼图(展示数据占比)
饼图适合 "展示各部分占总体的比例",比如成绩等级分布、各年龄段学生占比。
示例:用饼图展示 "成绩等级分布"
python
python
import matplotlib.pyplot as plt
import pandas as pd
# 1. 配置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'PingFang SC']
plt.rcParams['axes.unicode_minus'] = False
# 2. 读取数据并计算等级分布
df = pd.read_csv("students_data.csv", encoding="utf-8", dtype={"course_score": int})
# 添加成绩等级列
df["grade"] = df["course_score"].apply(lambda x: "A级(90+)" if x >=90 else ("B级(80-89)" if x>=80 else "C级(<80)"))
# 统计各等级数量
grade_count = df["grade"].value_counts()
print("成绩等级分布:")
print(grade_count)
# 3. 绘制饼图
fig, ax = plt.subplots(figsize=(6, 6), dpi=100)
# 定义颜色(避免默认颜色单调)
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1']
# 绘制饼图(autopct:显示百分比;startangle:起始角度;explode:突出某部分)
wedges, texts, autotexts = ax.pie(
x=grade_count.values, # 各部分数量
labels=grade_count.index, # 各部分标签
autopct='%1.1f%%', # 显示百分比(保留1位小数)
startangle=90, # 起始角度90度(让饼图更美观)
colors=colors, # 颜色列表
explode=(0.05, 0, 0) # 突出A级(偏移5%)
)
# 4. 美化饼图(调整文字样式)
ax.set_title("学生成绩等级分布", fontsize=14, pad=20)
# 调整百分比文字颜色和字号
for autotext in autotexts:
autotext.set_color('white') # 百分比文字白色
autotext.set_fontsize(11)
# 5. 保存图表
plt.savefig("grade_pie.png", bbox_inches='tight')
plt.show()
运行结果
-
控制台输出:
plaintext
plaintext成绩等级分布: grade B级(80-89) 3 A级(90+) 2 C级(<80) 1 Name: count, dtype: int64 -
生成的图表 :
grade_pie.png(圆形饼图,B 级占 50.0%,A 级占 33.3%,C 级占 16.7%,A 级部分轻微突出,百分比文字白色醒目)。
饼图适用场景
- 展示各部分占总体的比例(如市场份额、成绩等级占比);
- 类别数量不宜过多(建议不超过 6 类,否则饼图会拥挤)。
5. 实战 3:折线图(展示数据趋势)
折线图适合 "展示数据随时间或顺序的变化趋势",比如学生总分排名、月度销售额变化。
示例:用折线图展示 "学生总分排名"
python
python
import matplotlib.pyplot as plt
import pandas as pd
# 1. 配置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'PingFang SC']
plt.rcParams['axes.unicode_minus'] = False
# 2. 读取数据并计算学生总分
df = pd.read_csv("students_data.csv", encoding="utf-8", dtype={"course_score": int})
# 按姓名分组计算总分,按总分降序排序
student_total = df.groupby("name")["course_score"].sum().sort_values(ascending=False).reset_index()
print("学生总分排名:")
print(student_total)
# 3. 绘制折线图
fig, ax = plt.subplots(figsize=(8, 5), dpi=100)
# 绘制折线图(marker:添加数据点;linewidth:线宽;markersize:点大小)
ax.plot(
student_total["name"], # x轴:学生姓名
student_total["course_score"], # y轴:总分
marker='o', # 数据点为圆形
linewidth=2, # 线宽2像素
markersize=8, # 数据点大小8
color='#FF6B6B' # 线和点的颜色
)
# 4. 添加图表元素
ax.set_title("学生总分排名趋势", fontsize=14, pad=20)
ax.set_xlabel("学生姓名", fontsize=12)
ax.set_ylabel("总分(分)", fontsize=12)
ax.grid(True, alpha=0.3) # 添加网格(透明度0.3,不影响数据)
# 在每个数据点上添加数值标签
for i, row in student_total.iterrows():
ax.text(
i, # x坐标:行索引(0,1,2)
row["course_score"] + 2, # y坐标:总分+2(避免重叠)
str(row["course_score"]), # 显示的数值
ha='center', va='bottom', fontsize=11
)
# 5. 调整y轴范围
ax.set_ylim(150, 190)
# 6. 保存图表
plt.savefig("student_total_line.png", bbox_inches='tight')
plt.show()
运行结果
-
控制台输出:
plaintext
plaintext学生总分排名: name course_score 0 小红 183 1 小明 177 2 小刚 160 -
生成的图表 :
student_total_line.png(红色折线,从左到右依次是小红 183、小明 177、小刚 160,数据点为圆形,顶部有数值标签,背景有浅灰色网格)。
折线图适用场景
- 展示数据随顺序或时间的变化趋势(如排名、时间序列);
- 对比多个数据系列的趋势(如多个学生的多科成绩变化)。
三、可视化进阶:Seaborn 美化与复杂图表
Matplotlib 功能强大,但默认样式比较朴素;Seaborn 是基于 Matplotlib 的高级库,自带美观的样式和复杂图表(如箱线图、热力图),一行代码就能让图表颜值翻倍。
1. 安装与基础配置
▶ 安装 Seaborn
bash
bash
pip install seaborn
▶ 基础配置(启用 Seaborn 样式)
Seaborn 可以直接调用 Matplotlib 的 API,也可以用自己的样式:
python
python
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
# 1. 启用Seaborn默认样式(美观且无需手动调颜色)
sns.set_style("whitegrid") # 白色网格背景(适合大多数图表)
# 2. 解决中文字体(Seaborn依赖Matplotlib的字体配置)
plt.rcParams['font.sans-serif'] = ['SimHei', 'PingFang SC']
plt.rcParams['axes.unicode_minus'] = False
2. 实战 1:箱线图(展示数据分布与异常值)
箱线图适合 "展示数据的分布特征(中位数、四分位数、异常值)",比如各科成绩的分布范围、是否有异常高分 / 低分。
示例:用 Seaborn 绘制 "各科成绩箱线图"
python
python
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
# 1. 配置样式和中文字体
sns.set_style("whitegrid")
plt.rcParams['font.sans-serif'] = ['SimHei', 'PingFang SC']
plt.rcParams['axes.unicode_minus'] = False
# 2. 读取数据
df = pd.read_csv("students_data.csv", encoding="utf-8", dtype={"course_score": int})
# 3. 绘制箱线图(Seaborn一行代码)
fig, ax = plt.subplots(figsize=(8, 5), dpi=100)
sns.boxplot(
x="course_name", # x轴:课程名
y="course_score", # y轴:成绩
data=df, # 数据源
palette="Set2", # 颜色主题
ax=ax # 指定子图(和Matplotlib兼容)
)
# 4. 添加图表元素
ax.set_title("各科成绩分布箱线图", fontsize=14, pad=20)
ax.set_xlabel("课程名称", fontsize=12)
ax.set_ylabel("成绩(分)", fontsize=12)
# 调整y轴范围(0-100,符合成绩逻辑)
ax.set_ylim(0, 100)
# 5. 保存图表
plt.savefig("course_score_box.png", bbox_inches='tight')
plt.show()
箱线图解读
箱线图的每个 "箱子" 代表数据的核心分布:
- 箱子中间的线:中位数(50% 分位数);
- 箱子上下沿:25% 分位数和 75% 分位数(中间 50% 的数据在箱子内);
- 箱子外的线(须):数据的合理范围(通常是 1.5 倍四分位距);
- 须外的点:异常值(如 0 分或 100 分以外的极端值)。
运行结果
生成的course_score_box.png中,数学和英语的箱子清晰展示了各自的成绩分布 ------ 比如数学成绩的中位数略低于英语,说明英语整体成绩稍好,且两科都没有异常值。
3. 实战 2:热力图(展示变量间的相关性)
热力图适合 "展示两个分类变量的交叉统计结果",比如 "学生 - 课程 - 成绩" 的交叉表,用颜色深浅表示成绩高低。
示例:用 Seaborn 绘制 "学生 - 课程成绩热力图"
python
python
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
# 1. 配置样式和中文字体
sns.set_style("white") # 白色背景(热力图适合无网格)
plt.rcParams['font.sans-serif'] = ['SimHei', 'PingFang SC']
plt.rcParams['axes.unicode_minus'] = False
# 2. 读取数据并创建交叉表(学生-课程-成绩)
df = pd.read_csv("students_data.csv", encoding="utf-8", dtype={"course_score": int})
# 创建交叉表:行=学生,列=课程,值=成绩
score_cross = df.pivot_table(
index="name", # 行:学生姓名
columns="course_name", # 列:课程名
values="course_score" # 值:成绩
)
print("学生-课程成绩交叉表:")
print(score_cross)
# 3. 绘制热力图
fig, ax = plt.subplots(figsize=(6, 4), dpi=100)
sns.heatmap(
data=score_cross, # 数据源(交叉表)
annot=True, # 在热力图上显示数值
fmt="d", # 数值格式:整数
cmap="YlOrRd", # 颜色映射(黄色到红色,红色表示高分)
cbar=True, # 显示颜色条(右侧,解释颜色含义)
ax=ax
)
# 4. 添加图表元素
ax.set_title("学生-课程成绩热力图", fontsize=14, pad=20)
ax.set_xlabel("课程名称", fontsize=12)
ax.set_ylabel("学生姓名", fontsize=12)
# 5. 保存图表
plt.savefig("student_course_heatmap.png", bbox_inches='tight')
plt.show()
运行结果
-
控制台输出:
plaintext
plaintext学生-课程成绩交叉表: course_name 数学 英语 name 小明 85 92 小红 95 88 小刚 78 82 -
生成的图表 :
student_course_heatmap.png(热力图中,小红的数学成绩 95(深红色)、小明的英语成绩 92(深红色),小刚的数学成绩 78(浅黄色),颜色越深表示成绩越高,右侧颜色条标注了成绩范围)。
热力图适用场景
- 展示两个分类变量的交叉统计(如学生 - 课程 - 成绩、产品 - 地区 - 销量);
- 快速识别 "高值区域" 或 "低值区域"(如哪些学生在哪些课程上表现好)。
四、综合实操:学生成绩可视化报告(多图表组合)
咱们结合前面的所有图表类型,用 Matplotlib 和 Seaborn 制作一个 "学生成绩可视化报告"------ 在一个画布上绘制 4 个子图(柱状图、饼图、箱线图、热力图),形成完整的分析报告。
完整代码
python
python
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
def student_score_visual_report(input_file="students_data.csv", output_file="score_report.png"):
print("===== 学生成绩可视化报告生成中 =====")
# 1. 全局配置(样式、中文字体、分辨率)
sns.set_style("whitegrid")
plt.rcParams['font.sans-serif'] = ['SimHei', 'PingFang SC']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['figure.dpi'] = 100 # 全局分辨率
# 2. 读取并预处理数据
df = pd.read_csv(input_file, encoding="utf-8", dtype={"course_score": int})
# 添加成绩等级列
df["grade"] = df["course_score"].apply(lambda x: "A级(90+)" if x >=90 else ("B级(80-89)" if x>=80 else "C级(<80)"))
# 计算辅助数据
course_avg = df.groupby("course_name")["course_score"].mean().round(1) # 各科平均分
grade_count = df["grade"].value_counts() # 成绩等级分布
student_total = df.groupby("name")["course_score"].sum().sort_values(ascending=False).reset_index() # 学生总分
score_cross = df.pivot_table(index="name", columns="course_name", values="course_score") # 交叉表
# 3. 创建画布和4个子图(2行2列)
fig, axes = plt.subplots(2, 2, figsize=(12, 10)) # 2行2列,总宽12,高10
fig.suptitle("学生成绩可视化分析报告", fontsize=16, y=0.98) # 总标题(y=0.98:靠近顶部)
# 子图1:各科平均分柱状图(第1行第1列)
ax1 = axes[0, 0]
bars = ax1.bar(course_avg.index, course_avg.values, color='skyblue', edgecolor='black')
ax1.set_title("各科平均分对比", fontsize=12)
ax1.set_xlabel("课程名称")
ax1.set_ylabel("平均分(分)")
ax1.set_ylim(80, 90)
# 添加数值标签
for bar in bars:
height = bar.get_height()
ax1.text(bar.get_x()+bar.get_width()/2, height+0.5, str(height), ha='center', va='bottom')
# 子图2:成绩等级分布饼图(第1行第2列)
ax2 = axes[0, 1]
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1']
wedges, texts, autotexts = ax2.pie(grade_count.values, labels=grade_count.index, autopct='%1.1f%%',
startangle=90, colors=colors, explode=(0.05, 0, 0))
ax2.set_title("成绩等级分布", fontsize=12)
# 美化百分比文字
for autotext in autotexts:
autotext.set_color('white')
autotext.set_fontsize(10)
# 子图3:各科成绩箱线图(第2行第1列)
ax3 = axes[1, 0]
sns.boxplot(x="course_name", y="course_score", data=df, palette="Set2", ax=ax3)
ax3.set_title("各科成绩分布", fontsize=12)
ax3.set_xlabel("课程名称")
ax3.set_ylabel("成绩(分)")
ax3.set_ylim(0, 100)
# 子图4:学生-课程成绩热力图(第2行第2列)
ax4 = axes[1, 1]
sns.heatmap(score_cross, annot=True, fmt="d", cmap="YlOrRd", cbar=True, ax=ax4)
ax4.set_title("学生-课程成绩热力图", fontsize=12)
ax4.set_xlabel("课程名称")
ax4.set_ylabel("学生姓名")
# 4. 调整子图间距(避免标签重叠)
plt.tight_layout() # 自动调整间距
plt.subplots_adjust(top=0.93) # 预留总标题空间
# 5. 保存报告
plt.savefig(output_file, bbox_inches='tight', dpi=150) # 高分辨率保存(150dpi)
plt.close() # 关闭画布,释放内存
print(f"✅ 可视化报告已保存到:{output_file}")
print("===== 报告生成完成 =====")
# 运行报告生成函数
if __name__ == "__main__":
student_score_visual_report()
关键功能说明
- 多子图布局 :用
plt.subplots(2, 2)创建 2 行 2 列的子图,通过axes[行索引, 列索引]访问每个子图; - 全局样式:统一配置 Seaborn 样式和中文字体,确保所有子图风格一致;
- 间距调整 :
plt.tight_layout()自动调整子图间距,plt.subplots_adjust(top=0.93)为总标题预留空间,避免重叠; - 高分辨率保存 :保存时设置
dpi=150,让图表更清晰,适合打印或插入文档。
运行结果
生成的score_report.png包含 4 个子图,从不同维度展示学生成绩:
- 左上:各科平均分对比(英语略高);
- 右上:成绩等级分布(B 级占比最高);
- 左下:各科成绩分布(无异常值);
- 右下:学生 - 课程成绩热力图(小红数学最好,小明英语最好)。
五、新手必踩的 5 个坑:避坑指南
数据可视化看似简单,但新手容易在 "字体""布局""样式" 上踩坑,导致图表不美观或报错。咱们总结 5 个高频问题:
坑 1:中文字体乱码(最常见)
python
python
# 错误示例:未配置中文字体,图表中中文显示为方框
import matplotlib.pyplot as plt
plt.plot(["小明", "小红"], [177, 183])
plt.title("学生总分")
plt.show() # 标题"学生总分"显示为方框
解决:在代码开头添加字体配置:
python
python
plt.rcParams['font.sans-serif'] = ['SimHei', 'PingFang SC']
plt.rcParams['axes.unicode_minus'] = False
坑 2:子图布局重叠(标签被截断)
python
python
# 错误示例:多子图未调整间距,标签重叠
fig, axes = plt.subplots(2, 2, figsize=(8, 6))
# 绘制4个子图后,标签重叠
plt.savefig("overlap.png") # 部分标签被截断
解决 :添加plt.tight_layout()自动调整间距,或plt.subplots_adjust()手动调整:
python
python
plt.tight_layout() # 自动调整
# 或手动调整上下左右间距
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1)
坑 3:Seaborn 和 Matplotlib 样式冲突
python
python
# 错误示例:先画Matplotlib图表,再启用Seaborn样式,样式不生效
import seaborn as sns
import matplotlib.pyplot as plt
# 先画图表,再启用样式
plt.plot([1,2,3], [4,5,6])
sns.set_style("whitegrid") # 样式不生效
plt.show()
解决:先启用 Seaborn 样式,再绘制图表:
python
python
sns.set_style("whitegrid") # 先启用样式
plt.plot([1,2,3], [4,5,6]) # 再画图表
plt.show()
坑 4:饼图标签拥挤(类别过多)
python
python
# 错误示例:饼图类别超过6个,标签拥挤
grade_count = pd.Series([1,2,3,4,5,6,7], index=[f"等级{i}" for i in range(7)])
plt.pie(grade_count.values, labels=grade_count.index)
plt.show() # 标签重叠,无法看清
解决 :减少类别数量(合并相似类别),或用labeldistance调整标签距离:
python
python
plt.pie(grade_count.values, labels=grade_count.index, labeldistance=1.2) # 标签远离饼图
坑 5:保存图表时标签被截断
python
python
# 错误示例:未加bbox_inches='tight',标题被截断
plt.plot([1,2,3], [4,5,6])
plt.title("这是一个很长的标题,用来测试保存时是否被截断")
plt.savefig("cutoff.png") # 标题右侧被截断
解决 :保存时添加bbox_inches='tight':
python
python
plt.savefig("cutoff.png", bbox_inches='tight') # 自动适配所有标签
六、小结与下一篇预告
这篇你学到了什么?
- 可视化基础:理解数据可视化的价值,掌握 Matplotlib 的 "画布 - 子图 - 元素" 逻辑;
- Matplotlib 实战:绘制柱状图(对比)、饼图(占比)、折线图(趋势),添加标题、标签、数值等元素;
- Seaborn 进阶:用 Seaborn 美化图表,绘制箱线图(分布)、热力图(交叉统计),一行代码提升颜值;
- 综合报告:制作多子图的可视化报告,调整布局和分辨率,生成完整分析结果;
- 避坑指南:解决中文字体、子图重叠、样式冲突等常见问题。
下一篇预告
今天的可视化让数据 "说话",但前面的所有知识都是 "单机运行"------ 如果想让你的学生管理系统被多人访问(比如老师和学生都能查看成绩),就需要开发 Web 应用。下一篇咱们会学 Python 的 Web 框架Flask,结合前面的 Pandas 和可视化知识,开发一个 "在线学生成绩管理系统",支持浏览器访问、数据查询和图表展示,让你的项目从 "本地工具" 升级为 "Web 应用"。
如果这篇内容帮你掌握了数据可视化,欢迎在评论区分享你的 "可视化作品"(比如用图表分析你的消费数据),咱们一起交流进步~
