在 ggplot2 中将两个不同的 geoms 分开

Dodge two different geoms apart in ggplot2

假设我有两个不同的数据源。一种是重复观察,一种只是模型预测的平均值 +/- 标准误差。

n <- 30
obs <- data.frame(
  group = rep(c("A", "B"), each = n*3),
  level = rep(rep(c("low", "med", "high"), each = n), 2),
  yval = c(
    rnorm(n, 30), rnorm(n, 50), rnorm(n, 90),
    rnorm(n, 40), rnorm(n, 55), rnorm(n, 70)
  )
) %>%
  mutate(level = factor(level, levels = c("low", "med", "high")))

model_preds <- data.frame(
  group = c("A", "A", "A", "B", "B", "B"),
  level = rep(c("low", "med", "high"), 2),
  mean = c(32,56,87,42,51,74),
  sem = runif(6, min = 2, max = 5)
)

现在我可以很容易地将它们绘制在同一张图上

p <- ggplot(obs, aes(x = level, y = yval, fill = group)) +
  geom_boxplot() +
  geom_point(data = model_preds, aes(x = level, y = mean), size = 2, colour = "forestgreen") +
  geom_errorbar(data = model_preds, aes(x = level, y = mean, ymax = mean + sem, ymin = mean - sem), colour = "forestgreen", size = 1) +
  facet_wrap(~group)

并使用它直观地查看模型预测与观察结果之间的差异。

但我认为这看起来有点难看,所以理想情况下会想要 'dodge' 来自箱形图 geom 的点和误差线 geom。

如果你能原谅我的快速绘画,就像这样:

似乎 position_dodge() 可能是可行的方法,但我还没有弄清楚如何以这种方式组合两个不同的几何图形,文档也没有任何示例。

可能这是不可能的,但我想我会要求检查

由于图形语法清楚地将绘图的各个方面分开,因此无法在绘图的不同层(geoms 和 stats)之间传递信息。这也意味着位置调整不能跨层共享,因此它们可以以多层方式躲避。

你可以做的下一个最好的事情是在每一层中使用 position = position_nudge(),这样它们看起来就好像被躲过了一层。您可能还想为此调整箱线图和误差条的 width 参数。示例如下:

library(tidyverse)

n <- 30
obs <- data.frame(
  group = rep(c("A", "B"), each = n*3),
  level = rep(rep(c("low", "med", "high"), each = n), 2),
  yval = c(
    rnorm(n, 30), rnorm(n, 50), rnorm(n, 90),
    rnorm(n, 40), rnorm(n, 55), rnorm(n, 70)
  )
) %>%
  mutate(level = factor(level, levels = c("low", "med", "high")))

model_preds <- data.frame(
  group = c("A", "A", "A", "B", "B", "B"),
  level = rep(c("low", "med", "high"), 2),
  mean = c(32,56,87,42,51,74),
  sem = runif(6, min = 2, max = 5)
)

ggplot(obs, aes(x = level, y = yval, fill = group)) +
  geom_boxplot(position = position_nudge(x = -0.3),
               width = 0.5) +
  geom_point(data = model_preds, aes(x = level, y = mean), 
             size = 2, colour = "forestgreen",
             position = position_nudge(x = 0.3)) +
  geom_errorbar(data = model_preds, 
                aes(x = level, y = mean, ymax = mean + sem, ymin = mean - sem), 
                colour = "forestgreen", size = 1, width = 0.5,
                position = position_nudge(x = 0.3)) +
  facet_wrap(~group)

reprex package (v0.3.0)

于 2021 年 1 月 17 日创建