r - 使用 base R,如何创建一个 "joy plot"(又名山脊线图),其中有许多分布在彼此之上并具有垂直偏移?

标签 r plot distribution ridgeline-plot

我试图在 R 中实现的情节类型似乎被称为移动分布,as joy plot or as ridgeline plot :

joy-plot

Stackoverflow 中已经有一个问题,其记录的答案解释了如何使用 ggplot:How to reproduce this moving distribution plot with R?

但是,出于学习目的,我试图仅使用基本 R 图(没有格子、没有 ggplot、没有任何绘图包)来实现相同的目的。

为了开始,我生成了以下假数据来玩:

set.seed(2020)
shapes <- c(0.1, 0.5, 1, 2, 4, 5, 6)
dat <- lapply(shapes, function(x) rbeta(1000, x, x))
names(dat) <- letters[1:length(shapes)]

然后使用 mfrow 我可以实现这个:

par(mfrow=c(length(shapes), 1))
par(mar=c(1, 5, 1, 1))
for(i in 1:length(shapes))
{
    values <- density(dat[[names(dat)[i]]])
    plot(NA,
         xlim=c(min(values$x), max(values$x)),
         ylim=c(min(values$y), max(values$y)),
         axes=FALSE,
         main="",
         xlab="",
         ylab=letters[i])
    polygon(values, col="light blue")
}

我得到的结果是:

r-device-plot

很明显,在这里使用 mfrow(甚至 layout)不够灵活,而且还允许分布之间的重叠。

然后,问题是:我怎样才能仅使用基本的 R 绘图函数来重现这种类型的绘图?

最佳答案

这是一个基本的 R 解决方案。首先,我们计算所有的密度值,然后手动偏移 y 轴

vals <- Map(function(x, g, i) {
  with(density(x), data.frame(x,y=y+(i-1), g))
}, dat, names(dat), seq_along(dat))

然后,为了绘图,我们计算了总体范围,绘制了一个空图,并绘制了密度(反向以便它们堆叠)

xrange <- range(unlist(lapply(vals, function(d) range(d$x))))
yrange <- range(unlist(lapply(vals, function(d) range(d$y))))
plot(0,0, type="n", xlim=xrange, ylim=yrange, yaxt="n", ylab="", xlab="Value")
for(d in rev(vals)) {
  with(d, polygon(x, y, col="light blue"))
}
axis(2, at=seq_along(dat)-1, names(dat))

enter image description here

关于r - 使用 base R,如何创建一个 "joy plot"(又名山脊线图),其中有许多分布在彼此之上并具有垂直偏移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65334695/

相关文章:

r - 在 R 控制台中指定字体 - 多平台解决方案?

r - 如何计算连续行的时间差

mysql - 如何使用 Shiny 的mysql表创建图形?

R - 赋值和 mapply 函数错误 - 相同的错误 : "number of items to replace is not a multiple of replacement length"

algorithm - 最小化距离最近传感器的最大距离 : How to distribute x distance sensors in a N×M rectangle efficiently?

html - r knit html 如何创建一个简单的频率表,就像我们在书本上看到的那样?

R:使用 rockchalk 或 rgl 再现 3D 绘图

matlab - 如何在 MATLAB 中为 ax+by-c 画一条线?

matplotlib - 绘制 Budyko 曲线 (1974)

c++ - 如何测试某些数字是否沿区间均匀分布?