如何以相同的幅度抖动 geom_line 和 geom_point?

How to jitter both geom_line and geom_point by the same magnitude?

我有一个 ggplot2 线图,其中两条线具有明显的重叠。我正在尝试使用 position_jitterdodge() 以便它们更明显,但我无法以相同的方式获取线条和指向两个抖动的点。我试图仅水平抖动点和线(因为我不想建议对 y-axis 进行任何更改)。这是一个 MWE:

## Create data frames
dimension <- factor(c("A", "B", "C", "D"))
df <- data.frame("dimension" = rep(dimension, 2),
                 "value" = c(20, 21, 34, 32,
                             20, 21, 36, 29),
                 "Time" = c(rep("First", 4), rep("Second", 4)))
## Plot it
ggplot(data = df, aes(x = dimension, y = value,
                      shape = Time, linetype = Time, group = Time)) +
    geom_line(position = position_jitterdodge(dodge.width = 0.45)) +
    geom_point(position = position_jitterdodge(dodge.width = 0.45)) +
    xlab("Dimension") + ylab("Value")

产生丑陋的东西:

我显然在这里犯了一些根本性的错误:我应该怎么做才能使 geom_point 抖动跟随 geom_line 抖动?

一种解决方案是手动抖动点:

df$value_j <- jitter(df$value)

ggplot(df, aes(dimension, value_j, shape=Time, linetype=Time, group=Time)) +
  geom_line() +
  geom_point() +
  labs(x="Dimension", y="Value")

你的离散 X 轴的水平解决方案不是那么干净(当 ggplot2 这样做时它很干净 under the covers 因为它很好地为你处理轴和点转换)但它是可行的:

df$dim_j <- jitter(as.numeric(factor(df$dimension)))

ggplot(df, aes(dim_j, value, shape=Time, linetype=Time, group=Time)) +
  geom_line() +
  geom_point() +
  scale_x_continuous(labels=dimension) +
  labs(x="Dimension", y="Value")

仅水平的另一个选项是指定 position_dodge 并将其传递给每个 geom 的 position 参数。

pd <- position_dodge(0.4)

ggplot(data = df, aes(x = dimension, y = value,
                      shape = Time, linetype = Time, group = Time)) +
  geom_line(position = pd) +
  geom_point(position = pd) +
  xlab("Dimension") + ylab("Value")

2017 年 7 月,ggplot2 的开发人员在 position_jitter 函数 (https://github.com/tidyverse/ggplot2/pull/1996) 上添加了一个 seed 参数。

所以,现在(此处:ggplot2 3.2.1)您可以将参数 seed 传递给 position_jitter,以便在 [=18= 中获得相同的 jitter 效果]和geom_line(参见官方文档:https://ggplot2.tidyverse.org/reference/position_jitter.html

请注意,此 seed 参数在 geom_jitter 中尚不存在。

ggplot(data = df, aes(x = dimension, y = value,
                      shape = Time, linetype = Time, group = Time)) +
  geom_line(position = position_jitter(width = 0.25, seed = 123)) +
  geom_point(position = position_jitter(width = 0.25, seed = 123)) +
  xlab("Dimension") + ylab("Value")