如何在Seaborn相关性热力图中添加p值及解决相关报错
解决Seaborn相关性热力图同时显示相关系数与p值的报错问题
问题说明
需要生成包含4个变量的相关性热力图,要求每个单元格同时显示相关系数,以及换行置于括号内的对应p值。运行代码时触发如下报错:
ValueError: setting an array element with a sequence
报错指向代码行:
corr_matrix, pvalues = data.corr(method=lambda x, y: pearsonr(x, y))
报错原因
pd.DataFrame.corr()的method参数仅支持返回单个数值(即相关系数),但scipy.stats.pearsonr()返回的是(相关系数, p值)的元组,导致DataFrame无法将序列值存入矩阵元素,从而抛出错误。
解决方法
步骤1:分别计算相关系数矩阵和p值矩阵
- 用默认的
data.corr()直接生成标准皮尔逊相关系数矩阵 - 遍历所有变量对,调用
pearsonr()提取p值,构建同维度的p值矩阵
步骤2:自定义热力图标注
关闭Seaborn heatmap的annot自动标注,手动通过ax.text()在每个单元格写入组合后的文本,实现相关系数与p值的换行显示。
完整修正代码
import numpy as np import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from scipy.stats import pearsonr # 生成4变量的模拟数据集 np.random.seed(42) data = pd.DataFrame(np.random.randn(100, 4), columns=list('ABCD')) # 计算相关系数矩阵 corr_matrix = data.corr(method='pearson') # 计算p值矩阵 pvalues = pd.DataFrame(np.zeros_like(corr_matrix), columns=corr_matrix.columns, index=corr_matrix.index) for i in range(len(corr_matrix.columns)): for j in range(len(corr_matrix.columns)): if i != j: corr, p = pearsonr(data.iloc[:, i], data.iloc[:, j]) pvalues.iloc[i, j] = p else: # 对角线变量自身相关,p值设为NaN pvalues.iloc[i, j] = np.nan # 绘制热力图 mask = np.triu(np.ones_like(corr_matrix, dtype=bool)) sns.set(style='white') fig, ax = plt.subplots(figsize=(10, 8)) # 关闭自动标注,后续手动添加 sns.heatmap(corr_matrix, annot=False, cmap='coolwarm', mask=mask, cbar_kws={'shrink': 0.8}, ax=ax, vmin=-1, vmax=1, center=0) # 手动添加组合标注:相关系数 + 换行的p值 for i in range(corr_matrix.shape[0]): for j in range(corr_matrix.shape[1]): if i >= j: continue # 组合文本,实现换行 annot_text = '{:.2f}\n(p={:.2e})'.format(corr_matrix.iloc[i, j], pvalues.iloc[i, j]) # 热力图单元格中心坐标为(j+0.5, i+0.5) ax.text(j + 0.5, i + 0.5, annot_text, ha='center', va='center', fontsize=10, color='white') plt.title('Correlation Heatmap with P-values') plt.tight_layout() plt.show() plt.close()
内容的提问来源于stack exchange,提问作者Amilovsky
相关产品推荐
相关产品推荐

