热力图拿颜色当第三个维度,最适合一次扫一遍两两之间的关系。 vmin 和 vmax 必须固定,不然每张图各自动缩放,颜色没有可比性。 箱形图一次给五个数:最小值、Q1、中位数、Q3、最大值,还标出离群点。
上一篇看两个量的关系,这一篇看「一堆量两两之间的关系」,还有「几组数的分布」。 相关系数矩阵是 4 行 4 列,热力图是它最合适的画法。
一、相关系数矩阵
| 语文 | 数学 | 英语 | 总分 | |
|---|---|---|---|---|
| 语文 | 1.000 | 0.573 | 0.788 | 0.897 |
| 数学 | 0.573 | 1.000 | 0.518 | 0.818 |
| 英语 | 0.788 | 0.518 | 1.000 | 0.884 |
| 总分 | 0.897 | 0.818 | 0.884 | 1.000 |
矩阵是对称的,对角线全是 1——自己和自己必然完全相关。 语文和总分 0.897、英语和总分 0.884、数学和总分 0.818。 三科彼此之间是 0.573、0.518、0.788,都比它们各自和总分的相关弱。
总分是三个相加出来的,它和每一科必然相关。这种自己造的列不该进相关分析。
二、热力图:颜色当第三维
ax.imshow(mat.values, cmap='RdYlGn', vmin=-1, vmax=1) 把矩阵画成色块。
vmin 和 vmax 固定成 -1 和 1,颜色才有绝对含义:深绿强正相关,深红强负相关。
不固定范围的话,每次自动缩放,两张热力图没法对比。
fig.colorbar(im, ax=ax) 加色标。没有色标,颜色就是纯装饰,读者只能猜。
三、箱形图:一次给五个数
箱子的上边是 Q3、下边是 Q1,中间那条线是中位数,两根须是范围。 须外面单独标出来的点是离群值。 语文:中位数 84.0、Q1 76.00、Q3 89.50,IQR 是 13.50。
箱形图一次说清「中间在哪、多宽、有没有离群」。比看十个数快得多。 它的盲区是看不出双峰——要判断形状还得回头画直方图。
四、两张图怎么配
| 图 | 横轴是什么 | 适合看什么 |
|---|---|---|
| 热力图 | 变量(行列都是) | 两两之间的关系 |
| 箱形图 | 分组 | 每组内部的分布 |
热力图的行列都是变量,箱形图的横轴是分组。这是两者最容易混的地方。 前者回答「哪些量一起动」,后者回答「哪一组更齐、有没有异常」。
五、动手 Demo:热力图与箱形图
先算四列的相关系数矩阵并印出来,再画成热力图(固定 -1 到 1)。 最后画三科的箱形图,读一遍四分位。
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
DF = pd.DataFrame({
"语文": [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)
C = DF.corr()
print(C.round(3).to_string())
fig, ax = plt.subplots(figsize=(5, 4))
im = ax.imshow(C.values, cmap="RdYlGn", vmin=-1, vmax=1)
ax.set_xticks(range(4))
ax.set_xticklabels(C.columns, rotation=45)
ax.set_yticks(range(4))
ax.set_yticklabels(C.index)
fig.colorbar(im, ax=ax)
fig.tight_layout()
fig.savefig("heat.png")
Q1 = np.percentile(DF["语文"], 25)
Q3 = np.percentile(DF["语文"], 75)
print("语文 中位数 %.1f Q1 %.2f Q3 %.2f IQR %.2f"
% (DF["语文"].median(), Q1, Q3, Q3 - Q1))
实跑输出:
--------------------------------------------------------------------
热力图与箱形图
--------------------------------------------------------------------
① 相关系数矩阵
--------------------------------------------------------------------
| 行 | 语文 | 数学 | 英语 | 总分 |
|---|---:|---:|---:|---:|
| 语文 | 1.0 | 0.573 | 0.788 | 0.897 |
| 数学 | 0.573 | 1.0 | 0.518 | 0.818 |
| 英语 | 0.788 | 0.518 | 1.0 | 0.884 |
| 总分 | 0.897 | 0.818 | 0.884 | 1.0 |
四列两两算相关,得到一个 4 行 4 列的对称矩阵,对角线全是 1。
语文和总分 0.897,数学和总分 0.818,英语和总分 0.884。
三科彼此之间是 0.573、0.518、0.788,都比它们各自和总分的相关弱。
! 总分是三个相加出来的,它和每一科都必然相关。这种「自己造的列」不该进相关分析。
② 热力图:颜色当第三个维度
--------------------------------------------------------------------
imshow 把矩阵画成色块,vmin 和 vmax 固定成 -1 和 1,颜色才有可比性。
不固定范围的话,每次自动缩放,两张热力图没法对比。
! 热力图必须配 colorbar。没有色标,颜色就是纯装饰,读者只能猜。
③ 箱形图:一次给五个数
--------------------------------------------------------------------
箱子上下边是 Q3 和 Q1,中间那条线是中位数,两根须是范围,点出去的是离群值。
语文中位数 84.0、Q1 76.00、Q3 89.50。
! 箱形图一次说清「中间在哪、多宽、有没有离群」。比看十个数快得多。
④ 两张图怎么配
--------------------------------------------------------------------
热力图看「两两之间的关系」,适合一次扫一遍所有配对。
箱形图看「一组数的分布」,适合横向比较几组。
热力图的行列都是变量,箱形图的横轴是分组。这是两者最容易混的地方。
! 箱形图看不出双峰。要判断形状还得回头画直方图。
DF[ ["语文", "数学", "英语"]].sum(axis=1) 是按行加,总分那一列就这么来的。
corr() 会自动跳过非数值列。姓名、班级这类列不会进矩阵,也不会报错。
30 秒实验
- 把 vmin 和 vmax 去掉,看颜色怎么变(再画第二张对比)。
- 把 boxplot 里的三科换成「一班」和「二班」的总分,看两个箱子谁更宽。
- 想一想:为什么总分那一列不该放进相关分析?
常见误区
- 热力图不固定 vmin/vmax:每张图各自动缩放,颜色没法对比。
- 热力图不配 colorbar:颜色没有刻度,读者只能猜。
- 把自造的列放进相关分析:总分和每科都强相关,那是加法造出来的。
- 用箱形图判断双峰:箱形图只给五个数,看不出形状。
- 对整个 DF 做按行求和:碰到姓名这类字符串列会报 TypeError,得先挑出数值列。
自测三问(点开对答案)
1. 热力图的 vmin 和 vmax 为什么要固定? —— 固定之后颜色才有绝对含义,不同图之间才能对比。不固定则每张图各自缩放。 2. 箱形图那五个数分别是什么? —— 最小值、Q1、中位数、Q3、最大值。须外的点单独标出来是离群值。 3. 为什么「总分」不适合进相关矩阵? —— 它是三科相加造出来的列,和每一科都必然强相关,这种相关没有信息量。二维图都会了。下一篇上三维:3D 图、多子图,还有保存格式的选择。
- ☐ (本篇完,下一篇 5.11 3D 图、子图与保存)