堆叠密度图中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
相关产品推荐
相关产品推荐

