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

Python与R绘制同数据集密度函数图结果存在差异的原因问询

R与Python绘制分组密度图差异原因说明

核心原因1:密度归一化规则默认值不同

这是导致图形差异的最主要原因:

  • R的ggplot2::geom_density默认按分组单独归一化:每个组的密度曲线下面积都为1,完全不考虑组内样本量差异。你的样本中TARGET=1仅占1/25,但归一化后它的密度峰值会和占绝大多数的TARGET=0差不多高,会放大少数类的分布表现。
  • Python的seaborn.displot(kind='kde')默认common_norm=True:所有分组的密度总和的积分是1,密度值会按各组样本量加权。样本占比极低的TARGET=1的密度峰值会远低于TARGET=0,更符合类别不平衡的真实分布情况,这也是你觉得Python结果更符合预期的原因。

次要原因2:核带宽默认计算规则不同

分组密度的平滑程度由核函数带宽决定,两个工具的默认带宽规则不一致:

  • ggplot2默认使用nrd0(Silverman经验法则)计算带宽
  • seaborn默认使用scott规则计算带宽
    对于TARGET=1这种只有3个样本的极小样本组,带宽的微小差异都会导致曲线形状出现明显变化。

代码对齐方案

如果希望两种工具输出结果一致,可以调整参数抹平默认差异:

让R的绘图结果匹配Python默认效果

修改ggplot的密度映射,使用加权密度,同时对齐核参数即可:

# ggplot2 3.3.0及以上版本
ggplot(df,aes(x=varA))+
  geom_density(aes(fill=as.factor(TARGET), y = after_stat(density * n / sum(n))), 
               alpha=0.8, position="identity", bw = "scott", kernel = "gaussian")

# 旧版本ggplot2替换y映射为y = ..density.. * ..n.. / sum(..n..)即可

让Python的绘图结果匹配R默认效果

修改seaborn的common_norm参数为False,每组单独归一化,同时对齐核参数:

sns.displot(data=df, x="varA", kind="kde", hue='TARGET', fill=True, alpha=0.3, 
            common_norm=False, bw_method='silverman')
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 18:45:00