如何在ggplot上下分置的双直方图中添加对应正态密度曲线
解决方案
要给下方的Metric12直方图叠加对应的正态密度曲线,核心是匹配直方图的y轴反转逻辑,同时用该组数据的实际统计量生成曲线,具体修改如下:
修改后的完整代码
library(ggplot2) set.seed(1) dat = rbind(data.frame('val' = rnorm(100), 'met' = 'Metric1'), data.frame('val' = rt(100, 2), 'met' = 'Metric12')) ggplot(dat, aes(x = val, fill = met)) + # 上方Metric1直方图及标准正态曲线 geom_histogram(data = dat[dat$met == 'Metric1',], breaks = seq(-10, 10, 0.5), mapping = aes(y = after_stat(density)), colour = "black", alpha = 0.3) + stat_function(fun = dnorm, args = list(mean = 0, sd = 1)) + # 下方Metric12直方图及对应正态曲线 geom_histogram(data = dat[dat$met == 'Metric12', ], breaks = seq(-10, 10, 0.5), mapping = aes(y = -after_stat(density)), colour = "black", alpha = 0.3)+ # 关键:反转曲线y值,并用Metric12数据的均值和标准差生成正态曲线 stat_function( fun = dnorm, args = list(mean = mean(dat$val[dat$met == 'Metric12']), sd = sd(dat$val[dat$met == 'Metric12'])), mapping = aes(y = -after_stat(y)) ) + coord_cartesian(xlim = c(-10, 10))
关键说明
- 因为Metric12的数据集是t分布生成的,所以需要用该组数据自身的均值和标准差生成正态曲线,而非直接用标准正态参数(0,1),这样曲线才能和直方图的分布匹配。
- 下方直方图的y轴是
-after_stat(density),因此对应的正态曲线也需要通过aes(y = -after_stat(y))反转y值,才能和直方图对齐到同一侧。 - 如果不想单独计算统计量,也可以直接在函数内嵌入计算逻辑简化代码:
stat_function( fun = function(x) -dnorm(x, mean = mean(dat$val[dat$met == 'Metric12']), sd = sd(dat$val[dat$met == 'Metric12'])) )
内容的提问来源于stack exchange,提问作者Bogaso
相关产品推荐
相关产品推荐

