如何在同一直方图中绘制多个函数的密度分布?
同一张直方图叠加多个密度函数实现方案(R语言)
核心要点是必须将直方图纵轴设置为密度尺度,否则密度曲线和直方图尺度不匹配无法对齐,你可以根据使用的绘图系统选择对应实现方式。
基础R原生绘图实现
- 绘制直方图时指定
freq = FALSE,将纵轴从计数转为密度 - 多组直方图叠加时设置填充色半透明,避免完全遮挡下层内容
- 用
curve()绘制理论分布密度、lines(density())绘制样本核密度曲线,通过add = TRUE参数叠加到现有画布 - 最后添加图例区分不同分组的图形元素
# 固定随机种子,结果可复现 set.seed(123) # 生成两组示例分布数据 data_norm1 <- rnorm(1000, mean = 0, sd = 1) data_norm2 <- rnorm(1000, mean = 2, sd = 1.5) # 绘制第一组直方图 hist(data_norm1, freq = FALSE, col = rgb(1, 0, 0, 0.25), # 半透红色填充 xlim = c(-4, 7), ylim = c(0, 0.5), main = "直方图叠加多密度曲线示例", xlab = "观测值", ylab = "密度") # 叠加第二组半透直方图 hist(data_norm2, freq = FALSE, col = rgb(0, 0, 1, 0.25), # 半透蓝色填充 add = TRUE) # 叠加理论密度曲线 curve(dnorm(x, mean = 0, sd = 1), col = "red", lwd = 2, add = TRUE) curve(dnorm(x, mean = 2, sd = 1.5), col = "blue", lwd = 2, add = TRUE) # 叠加样本核密度估计曲线 lines(density(data_norm1), col = "darkred", lwd = 2, lty = 2) lines(density(data_norm2), col = "darkblue", lwd = 2, lty = 2) # 添加图例 legend("topright", legend = c("N(0,1)样本分布", "N(2,1.5)样本分布", "N(0,1)理论密度", "N(2,1.5)理论密度", "N(0,1)核密度", "N(2,1.5)核密度"), fill = c(rgb(1,0,0,0.25), rgb(0,0,1,0.25), NA, NA, NA, NA), col = c(NA, NA, "red", "blue", "darkred", "darkblue"), lwd = c(NA, NA, 2, 2, 2, 2), lty = c(NA, NA, 1, 1, 2, 2), bty = "n")
ggplot2 绘图实现
ggplot2语法更简洁,自动生成分组图例,适合快速出出版级图片:
- 先将数据转换为长格式数据框,用分组列映射颜色、填充属性
- 直方图图层指定
y = after_stat(density)匹配密度尺度,位置参数设为position = "identity"取消默认堆叠 - 用
geom_density()叠加核密度曲线,stat_function()叠加自定义理论密度函数
library(ggplot2) # 构造长格式示例数据 df <- data.frame( value = c(data_norm1, data_norm2), group = rep(c("N(0,1)样本", "N(2,1.5)样本"), each = 1000) ) ggplot(df, aes(x = value, fill = group, color = group)) + geom_histogram(aes(y = after_stat(density)), alpha = 0.3, position = "identity", binwidth = 0.3) + geom_density(linewidth = 1, alpha = 0.2, show.legend = FALSE) + # 叠加理论密度曲线 stat_function(fun = dnorm, args = list(mean = 0, sd = 1), color = "darkred", linewidth = 1, linetype = 2) + stat_function(fun = dnorm, args = list(mean = 2, sd = 1.5), color = "darkblue", linewidth = 1, linetype = 2) + scale_fill_manual(values = c("N(0,1)样本" = "red", "N(2,1.5)样本" = "blue")) + scale_color_manual(values = c("N(0,1)样本" = "red", "N(2,1.5)样本" = "blue")) + labs(title = "ggplot2版本多密度叠加直方图", x = "观测值", y = "密度") + theme_bw()
注意:如果需要叠加其他分布(比如指数分布、伽马分布、自定义分布),只需要替换
curve()或stat_function()里的函数名和对应参数即可。
参考效果如下:
内容的提问来源于stack exchange,提问作者Fabricio Quinto
相关产品推荐
相关产品推荐

