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

堆叠密度图中stat_density的计算逻辑与展示含义咨询

堆叠密度图的本质与stat_density计算逻辑解析

问题背景

用diamonds数据集制作堆叠密度图时,出现了和预期不符的情况:统计表格显示Fair切工的钻石仅1610颗,Ideal切工多达21551颗,但堆叠密度图(尤其是position="fill"的版本)里五种切工的占比近乎相等,完全没体现出样本量的差异。

复现代码

library(tidyverse)
library(patchwork)

# 堆叠密度图(position="stack")
p1 <- diamonds %>%
  ggplot() +
  geom_density(aes(x = price, fill = cut), position = "stack")

# 归一化堆叠密度图(position="fill")
p2 <- diamonds %>%
  ggplot() +
  geom_density(aes(x = price, fill = cut), position = "fill")

# 组合展示图表
p1 / p2 + plot_layout(guides = "collect")

结果展示

堆叠密度图

堆叠密度图

各切工钻石数量统计

table(diamonds$cut)
#>
#>      Fair      Good Very Good   Premium     Ideal
#>      1610      4906     12082     13791     21551

核心解答

1. 堆叠密度图到底展示什么?

密度图的核心是归一化后的概率分布:默认情况下,每个分组的密度曲线下方总面积为1,只反映该分组内数据的相对分布形态,和绝对样本量无关。

  • position="stack"的堆叠密度图:纵轴是各分组密度的总和,每个分组的高度对应自身的密度值。因为每个分组已被归一到面积为1,样本量的多少不会直接体现在高度上,只会体现该组在price区间上的分布特征。
  • position="fill"的版本:会把堆叠后的总高度归一为1,此时纵轴代表的是某一price区间内,各切工钻石的密度占所有切工总密度的比例。由于每个分组的密度已经单独归一,样本量差异被完全抹平,所以看起来各切工占比接近。

2. stat_density的计算逻辑

stat_density在ggplot中的默认行为:

  • 对每个分组单独执行核密度估计(KDE)
  • 默认参数scale="area",即把每个分组的密度曲线下面积强制归一为1,这样密度只反映分组内数据的分布形态,和样本量脱钩
  • 若要让密度反映样本量差异,可修改参数为scale="count",此时密度曲线下面积等于该分组的样本量,堆叠后纵轴代表各分组的频率总和,样本量多的分组会在图中体现出明显更高的高度。

修正示例(体现样本量差异)

如果想同时展示分布形态和样本量差异,可使用以下代码:

diamonds %>%
  ggplot() +
  geom_density(aes(x = price, fill = cut), position = "stack", scale = "count")

这样Ideal切工的曲线高度会明显高于Fair切工,和样本量的实际差异一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 07:27:27