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

如何用scipy.stats.probplot绘制p值的负log10分布QQ图

解决方法

你的问题出在对probplot的使用逻辑理解上:R代码是将转换后的理论均匀分位数与转换后的样本p值做对比,而你之前的Python代码错误地将转换后的p值(服从指数分布)与原始均匀分布的分位数做了对比,自然无法得到重合的对角线。

以下是两种正确实现方式:

方法一:用probplot对接指数分布

当p值服从均匀分布时,-log10(p)服从指数分布(参数为scale=1/np.log(10))。直接用这个分布作为probplot的对比基准即可:

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# 生成模拟数据(替换成你的真实p值数据)
p_values_data = np.random.uniform(0, 1, 1000)

# 转换p值
transformed_p = -np.log10(p_values_data)

# 计算指数分布的scale参数
scale_param = 1 / np.log(10)

# 绘制QQ图
stats.probplot(transformed_p, dist="expon", sparams=(0, scale_param), plot=plt)
plt.title("QQ Plot: -log10(p值) vs 理论指数分布")
plt.show()

方法二:手动实现与R完全一致的样本vs样本QQ图

如果要完全复刻R中qqplot的逻辑(直接对比转换后的理论分位数和转换后的样本分位数),可以手动计算理论分位数后绘制:

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

# 生成模拟数据(替换成你的真实p值数据)
p_values_data = np.random.uniform(0, 1, 1000)
n = len(p_values_data)

# 计算理论分位数(对应R中的ppoints)
theoretical_quantiles = -np.log10(stats.uniform.ppf(np.linspace(0.5/n, 1-0.5/n, n)))

# 计算样本分位数
sample_quantiles = np.sort(-np.log10(p_values_data))

# 绘制QQ图
plt.scatter(theoretical_quantiles, sample_quantiles, alpha=0.6)
plt.plot([min(theoretical_quantiles), max(theoretical_quantiles)], 
         [min(theoretical_quantiles), max(theoretical_quantiles)], 
         'r--', label="参考对角线")
plt.xlabel("理论 -log10(均匀分布) 分位数")
plt.ylabel("样本 -log10(p值) 分位数")
plt.legend()
plt.show()

内容的提问来源于stack exchange,提问作者Ozan.kah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 01:55:08