如何创建可在同一纵坐标叠加多PDF的R山脊线图?
问题:如何在同一纵坐标位置叠加绘制多组PDF的山脊线图
我需要创建一幅山脊线图,让多个概率密度函数(PDF)在同一纵坐标位置叠加,并通过颜色区分。以下是复现问题的示例数据和异常情况:
生成示例数据框
通过自定义函数生成包含模型名称、山脊线层级(id)、PDF的x值和密度值的数据集:
makedfs <- function(name, id, mu, sig) { vals <- exp(rnorm(1000, mean=mu, sd=sig)) pdf <-density(vals) model <- rep(name, length(pdf$x)) prox <- rep(id, length(pdf$x)) df <- data.frame(model, prox, pdf$x, pdf$y) colnames(df) <- c("name", "id", "x", "pdf") return(df) } df1 <- makedfs("model1", 0, log(1), 1) df2 <- makedfs("model2", 0, log(0.5), 2) df3 <- makedfs("model1", 1, log(0.2), 0.8) df4 <- makedfs("model2", 1, log(1), 1) df <- rbind(df1, df2, df3, df4)
数据集预览:
name id x pdf 1 model1 0 -0.6541933 0.0003544569 2 model1 0 -0.5999428 0.0007800386 3 model1 0 -0.5456924 0.0016274229 4 model1 0 -0.4914420 0.0032231582 5 model1 0 -0.4371915 0.0060682580
预期效果与绘制异常
预期在山脊线图的y=0位置看到以下两条PDF曲线:
plot(df1$x, df1$pdf, type ="l", col=1, xlim=c(-6,6), xlab = "x", ylab = "pdf") lines(df2$x, df2$pdf, col=2) legend("topleft", c("df1", "df2"), col = 1:2, lty = 1)
但使用ggplot2绘制山脊线图时,曲线和填充出现异常:
library(ggplot2) p <- ggplot(df, aes(x=x, y=id, height = pdf, group = name, fill = name)) + geom_ridgeline(alpha = 0.5, scale = 1) + scale_y_continuous(limits = c(0, 5)) + scale_x_continuous(limits = c(-6, 6))
解决方案
问题出在分组逻辑和数值缩放两个方面,修正后的代码如下:
library(ggplot2) p <- ggplot(df, aes(x = x, y = id, height = pdf, group = interaction(id, name), fill = name)) + geom_ridgeline(alpha = 0.5, scale = 100) + # 放大PDF高度至可见 scale_y_continuous(breaks = c(0, 1), labels = c("层级0", "层级1")) + scale_x_continuous(limits = c(-6, 6)) + labs(x = "x", y = "山脊线层级", fill = "模型") print(p)
关键修正点:
- 分组逻辑:使用
interaction(id, name)作为分组依据,确保每个(山脊线层级+模型)组合是独立的绘图单元,避免跨层级的同模型数据被错误合并 - 数值缩放:由于PDF的密度值量级极小(0.001~0.xx),将
scale参数调至100,让曲线高度放大到可清晰观察的程度 - 基线映射:保留
y=id的映射,确保同一层级的所有模型曲线都基于同一纵坐标基线绘制,实现叠加效果
内容的提问来源于stack exchange,提问作者a11
相关产品推荐
相关产品推荐

