Seaborn 的参数直接写列名,给 data、x、y 就自己分组算均值,不用先 groupby。 annot=True 把数值标在热力图格子里,比只给颜色强十倍。 五个问题对应五张图,没有一张图能同时回答两个问题。
前十一篇都在 Matplotlib 里打转。这一篇换 Seaborn——它的语法更短,默认配色更好。 代价是它对「精细控制」弱一些,复杂布局还得回到 Matplotlib。
一、Seaborn 吃 DataFrame
sns.barplot(data=df, x='班级', y='语文'),一行出图。
它自己按班级分组、自己算均值、自己画误差棒。Pandas 得先 groupby 再 plot。
参数直接写列名,不用写 df['列名']。这是 Seaborn 的语法风格。
代价是列名必须是字符串,带空格或特殊字符时要小心。
二、箱形图与热力图
sns.boxplot(data=df[ ['语文','数学','英语']]) 一次画三个箱子。
sns.heatmap(corr, annot=True, fmt='.2f', cmap='RdYlGn') 把数值标在格子里。
annot=True 是标注,fmt 管小数位,vmin/vmax 固定颜色范围。
热力图上标数值,比只给颜色强十倍。颜色是辅助,数是结论。 Seaborn 默认配色比 Matplotlib 好看,但默认字体不带中文,要单独设 font。
三、综合案例:一张四子图
柱形比均值、箱形看分布、散点看关系、直方看形状,四块拼成一张纸。 整张图 44366 字节,2 乘 2 布局,figsize 10 乘 7。 综合图的意义是「一屏之内说完一件事」。超过四个子图就该拆成两页。
四个子图的标题要短,两到四个字。长了会互相挤,tight_layout 也救不回来。
四、五个案例的选择逻辑
| 要回答的问题 | 用哪张图 |
|---|---|
| 哪个班考得好 | 柱形图(比均值) |
| 哪个班更齐 | 箱形图(看宽度) |
| 语文和数学有关系吗 | 散点图(看形状) |
| 总分集中在哪一段 | 直方图(看区间) |
| 三科之间谁跟谁近 | 热力图(看两两) |
五个问题对应五种图,没有一张图能同时回答两个问题。 所以「画一张大图说清一切」是伪需求。要说清五件事,就得五张图。 先列问题,再配图。顺序反了就会画一堆好看但答不上问题的图。
五、动手 Demo:Seaborn 与五个综合案例
用 Seaborn 画柱形、箱形、热力图各一张,再用 Matplotlib 拼一张 2 乘 2 综合图。 重点看 Seaborn 那三行有多短。
import os
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
sns.set_theme(style="whitegrid", font="SimHei",
rc={"axes.unicode_minus": False})
N = ["张伟", "王芳", "李娜", "刘洋", "陈静",
"杨帆", "赵敏", "黄磊", "周涛", "吴霞"]
DF = pd.DataFrame({
"姓名": N,
"班级": ["一班"] * 5 + ["二班"] * 5,
"语文": [88, 92, 75, 85, 90, 68, 95, 72, 83, 79],
"数学": [92, 95, 68, 88, 73, 82, 91, 65, 86, 90],
"英语": [85, 90, 80, 79, 95, 71, 88, 60, 84, 87],
})
DF["总分"] = DF[ ["语文", "数学", "英语"]].sum(axis=1)
fig, ax = plt.subplots(figsize=(5, 4))
sns.barplot(data=DF, x="班级", y="语文", ax=ax, errorbar=None)
fig.tight_layout()
fig.savefig("sns_bar.png")
fig, ax = plt.subplots(figsize=(5, 4))
sns.heatmap(DF[ ["语文", "数学", "英语"]].corr(), annot=True,
fmt=".2f", cmap="RdYlGn", vmin=-1, vmax=1, ax=ax)
fig.tight_layout()
fig.savefig("sns_heat.png")
print("两张图 %d / %d 字节" % (os.path.getsize("sns_bar.png"),
os.path.getsize("sns_heat.png")))
实跑输出:
--------------------------------------------------------------------
Seaborn 与五个综合案例
--------------------------------------------------------------------
① Seaborn 吃 DataFrame
--------------------------------------------------------------------
同样一张柱图,Seaborn 只要一行:给 data、给 x、给 y,它自己分组算均值。
Pandas 要先 groupby 再 plot,Seaborn 一句话。这是它最省事的地方。
! Seaborn 的参数直接写列名,不用写 df['列名']。这是它的语法风格。
② 箱形图与热力图
--------------------------------------------------------------------
annot=True 把数值标在格子里,fmt='.2f' 管小数位。
热力图上标数值,比只给颜色强十倍。颜色是辅助,数是结论。
! Seaborn 的默认配色比 Matplotlib 好看,但默认字体不带中文,要设 font。
③ 综合案例:一张四子图看全一个班
--------------------------------------------------------------------
四张图:比均值、看分布、看关系、看形状。一张纸交代完一个班。
整张图 44366 字节,2 乘 2 布局,figsize 10 乘 7。
! 综合图的意义是「一屏之内说完一件事」。超过四个子图就该拆成两页。
④ 五个案例的选择逻辑
--------------------------------------------------------------------
| 要回答的问题 | 用哪张图 |
|---|---|
| 哪个班考得好 | 柱形图(比均值) |
| 哪个班更齐 | 箱形图(看宽度) |
| 语文和数学有关系吗 | 散点图(看形状) |
| 总分集中在哪一段 | 直方图(看区间) |
| 三科之间谁跟谁近 | 热力图(看两两) |
五个问题对应五种图,没有一张图能同时回答两个问题。
所以「画一张大图说清一切」是伪需求。要说清五件事,就得五张图。
! 先列问题,再配图。顺序反了就会画一堆好看但答不上问题的图。
errorbar=None 是关掉误差棒。不关的话它会自动画置信区间,柱子变复杂。
Seaborn 画图也要传 ax=。不传就画到「当前图」上,多子图时会对不上位置。
30 秒实验
- 把 errorbar=None 去掉,看柱子上多出什么。
- 把 sns.set_theme 的 style 换成 'darkgrid',看背景怎么变。
- 想一想:Seaborn 这么省事,为什么还需要 Matplotlib?
常见误区
- Seaborn 不传 ax:多子图时画到别处去了。
- 忘了设 font:图里中文全是方块。
- 热力图不给 vmin/vmax:每张图各自缩放,颜色没法对比。
- 一张图塞八个子图:多到看不清,不如拆成两页。
自测三问(点开对答案)
1. Seaborn 比 Matplotlib 省事在哪? —— 它能直接吃 DataFrame、直接写列名,自己分组算统计量;Matplotlib 得先算好再画。 2. 为什么 Seaborn 画图也要传 ax? —— 不传就作用在「当前图」上,多子图场景会画错位置。 3. 为什么说「一张图说清一切」是伪需求? —— 一个问题对应一种图。要回答五个问题就得五张图,挤在一起谁都看不清。第 5 章十二篇到此结束。第 6 章换个更底层的东西:NumPy 数组。
- ☐ (本篇完,下一篇 6.1 初识 NumPy:数组和列表差在哪)