热力图输入必须是二维数值矩阵,不能直接使用含非数值列的原始DataFrame;需先用select_dtypes筛选数值列,再调用corr()生成相关矩阵,否则会报TypeError或ValueError。

热力图的输入必须是二维数值矩阵,不是原始DataFrame
Seaborn 的 sns.heatmap() 不接受带字符串列名或混合类型(如含分类变量)的原始 DataFrame。它只认纯数值的二维结构——通常是相关系数矩阵、协方差矩阵,或者你自己算好的交叉统计表。
常见错误是直接传入含非数值列的 DataFrame,结果报错:TypeError: unsupported operand type(s) for -: 'str' and 'str' 或 ValueError: data must be 2-dimensional。
正确做法是先提取数值列,再计算相关性:
- 用
df.select_dtypes(include='number')筛出数值列 - 调用
.corr()得到pd.DataFrame类型的相关矩阵(默认皮尔逊) - 若需其他方法(如 spearman),显式传参:
df.corr(method='spearman')
中文标签显示乱码?得提前配置 matplotlib 字体
Seaborn 基于 matplotlib,而后者默认不支持中文。不处理的话,坐标轴和标题会变成方块或空格,但不会报错,容易误以为绘图失败。
立即学习“Python免费学习笔记(深入)”;
关键不是改 Seaborn 设置,而是改底层 matplotlib 的字体配置:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 运行前加两行:
import matplotlib.pyplot as plt和plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS', 'DejaVu Sans'] - 再加一行确保负号正常:
plt.rcParams['axes.unicode_minus'] = False - 注意:
SimHei是 Windows 默认中文字体;macOS 推荐'Arial Unicode MS'或'Heiti SC';Linux 可用'WenQuanYi Zen Hei'
想看显著性?Seaborn 本身不提供 p 值标注,得自己加
sns.heatmap() 只画数值,不管统计显著性。如果你需要在热力图上标出哪些相关系数达到 p
典型流程是:
- 用
scipy.stats.pearsonr()对每对数值列循环计算 r 值和 p 值 - 构造一个布尔掩码矩阵(如
p_values ),再用 <code>np.where()把显著位置标记为'*',不显著设为空字符串 - 把该标记矩阵传给
annot参数,并设fmt='s'(字符串格式)
示例片段:
import numpy as np
from scipy.stats import pearsonr
corr = df.corr()
p_values = np.zeros_like(corr)
for i in range(len(corr.columns)):
for j in range(len(corr.columns)):
_, p = pearsonr(df.iloc[:, i], df.iloc[:, j])
p_values[i, j] = p
mask = np.where(p_values < 0.05, '*', '')
sns.heatmap(corr, annot=True, fmt='.2f', cbar_kws={'shrink': .8}, annot_kws={'size': 10})
变量太多导致热力图挤成一条线?得控制行列数量或调整 figsize
当数值变量超过 20 个,sns.heatmap() 默认尺寸下字体会重叠、颜色条变窄、甚至坐标轴标签被截断——这不是 bug,是密度超限。
实用解法不是硬扛,而是主动降维或裁剪:
- 优先用
df.corr().abs().unstack().sort_values(ascending=False)查最高相关对,聚焦分析强关联子集 - 用
df.corr().loc[subset_cols, subset_cols]手动指定行列子集(比如只看前 12 个变量) - 必须全画?那就调大画布:
plt.figure(figsize=(14, 12)),再调小字体:annot_kws={'size': 8} - 避免用
xticklabels=True(默认已开),除非你真想关掉标签节省空间
热力图本质是探索性工具,不是汇报终稿;变量一多,优先考虑聚类排序(clustermap)或分组绘制,而不是堆满所有变量。

















