You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python的Seaborn密度图中标记p值或自定义值?

没问题!我刚好做过类似的需求,在Seaborn里结合Matplotlib就能实现带p值(或自定义值)标记的密度图,下面给你一套完整的方案,包括代码示例和详细解释:

在Seaborn中制作带p值/自定义值标记的密度图

核心思路

Seaborn本身没有直接添加p值标记的内置函数,但它是基于Matplotlib构建的,所以我们可以用Seaborn完成密度图的绘制,再用Matplotlib的底层绘图工具添加标记线条和文本,完全能适配报告的美观需求。

完整代码示例

1. 导入所需库

import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import ttest_ind
import pandas as pd
import numpy as np

2. 准备数据(替换为你的真实数据即可)

# 生成两组模拟数据(你可以直接替换成自己的数据集)
np.random.seed(42)  # 设置随机种子保证结果可复现
group1 = np.random.normal(loc=5, scale=1.5, size=200)
group2 = np.random.normal(loc=7, scale=1.2, size=200)

# 整理成Seaborn友好的DataFrame格式
df = pd.DataFrame({
    'Measurement': np.concatenate([group1, group2]),
    'Group': ['Control']*200 + ['Treatment']*200
})

3. 计算p值(或直接定义自定义值)

如果需要统计计算的p值,用scipy完成;如果是自定义值,直接跳过这一步定义标签即可:

# 计算两组独立样本t检验的p值
stat, p_value = ttest_ind(group1, group2)
# 格式化p值文本,适配报告展示(比如p<0.001的情况)
p_label = f'p = {p_value:.3f}' if p_value >= 0.001 else 'p < 0.001'

# 若用自定义值,直接替换成你需要的文本:
# p_label = 'Custom Sig: 0.002'

4. 绘制密度图并添加标记

# 设置适合报告的绘图风格
sns.set_style("whitegrid")
plt.figure(figsize=(10, 6))

# 绘制带填充的两组密度图
ax = sns.kdeplot(data=df, x='Measurement', hue='Group', fill=True, alpha=0.5, linewidth=2)

# --- 添加标记线条和p值文本 ---
# 取两组均值的中间位置作为标记竖线的横坐标
mid_x = (group1.mean() + group2.mean()) / 2
# 取密度图最大高度的90%作为文本位置,避免超出图范围
max_y = ax.get_ylim()[1] * 0.9

# 画一条虚线竖线
ax.axvline(x=mid_x, ymin=0, ymax=0.8, color='black', linestyle='--', linewidth=1.5)
# 在竖线顶部添加加粗的p值文本
ax.text(mid_x, max_y, p_label, ha='center', va='bottom', fontsize=12, fontweight='bold')

# 调整图的标签和标题
ax.set_xlabel('Measurement Value', fontsize=12)
ax.set_ylabel('Density', fontsize=12)
ax.set_title('Density Plot with Statistical Significance', fontsize=14, fontweight='bold')

# 移除右上角多余边框,让图更简洁
sns.despine()

plt.show()

样式自定义技巧

如果你想模仿R中ggsignif的横向标记样式(连接两组密度峰值),可以把竖线换成横线:

# 取两组分布的峰值横坐标(这里用均值近似)
peak_x1 = group1.mean()
peak_x2 = group2.mean()
# 画横向实线连接两组
ax.hlines(y=max_y, xmin=peak_x1, xmax=peak_x2, color='black', linestyle='-', linewidth=1.5)
# 在横线中间添加文本
ax.text((peak_x1 + peak_x2)/2, max_y + 0.01, p_label, ha='center', va='bottom', fontsize=12)

你还可以自由调整线条的颜色、样式(比如linestyle=':')、粗细,文本的字体大小、颜色,完全适配你的报告风格。

内容的提问来源于stack exchange,提问作者josefrangl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:15:48