R 选择性 ggplot geom_point(position = position_dodge())

R selective ggplot geom_point(position = position_dodge())

在下面的图中,我想避开彩色形状,而不是 1 的形状,以便虚线与 1 对齐。需要避开彩色形状,以免它们在同一时间点相互重叠。这是生成虚拟数据和绘图的代码。有没有办法选择性的躲避同一个geom_point?

的点
df <- data.frame(id = factor(sort(rep(seq(1,5),2))),
                 time = rep(c(3,6), 5),
                 cat1 = c(sample(c('good', 'ok', 'bad'), 2),
                          sample(c('good', 'ok', 'bad'), 2),
                          sample(c('good', 'ok', 'bad'), 2),
                          sample(c('good', 'ok', 'bad'), 2),
                          sample(c('good', 'ok', 'bad'), 2)),
                 cat2 = c(sample(c('a', 'b', 'c', 'd'), 2), 
                          sample(c('a', 'b', 'c', 'd'), 2),
                          sample(c('a', 'b', 'c', 'd'), 2),
                          sample(c('a', 'b', 'c', 'd'), 2),
                          sample(c('a', 'b', 'c', 'd'), 2))) %>%
  pivot_longer(cols = c('cat1', 'cat2'), names_to='type', names_prefix = 'value', values_to = 'value') %>%
  plyr::rbind.fill(data.frame(id = factor(seq(1,5)), 
        time = 9,
        time2 = 9,
        type = 'off',
        value = c(1, NA, NA, 1, 1))) %>%
  dplyr::arrange(id, time)

ggplot(df, aes(x = id, y = time)) +
  geom_point(aes(id, time, colour = value, shape = value), size = 2, position = position_dodge(width = 0.7)) +
  geom_segment(data = df[df$type == 'off',], aes(x = id, xend = id, y = 6,
                                          yend = time2), colour = 'black', linetype = 'dotted') +
  coord_flip() +
  scale_shape_manual(values = c(13, 17, 17, 17, 17, 16, 16, 16, 15, 15, 15, 15)) +
  scale_colour_manual(values = c('black', 'purple', 'green', '#ffff66', 'red',
                                 'green', '#ffff66', 'red', 
                                 'green', '#ffff66', 'pink')) +
  guides(fill = guide_legend(order = 2), shape = guide_legend(override.aes = list(size = 3)))

防止一个(或多个)点躲避的一种方法是进行两次 geom_point() 调用:一个被躲避(并排除有问题的点),一个不被躲避并包括点

ggplot(df, aes(x = id, y = time)) +
  geom_point(
    data = subset(df, value=="1"),
    aes(colour = value, shape = value), size = 2) +
  geom_point(
    data = subset(df, value!="1"),
    aes(colour = value, shape = value),
    size = 2, position = position_dodge(width = 0.7)) +
  
  geom_segment(data = df[df$type == 'off',], aes(x = id, xend = id, y = 6,
                                                 yend = time2), colour = 'black', linetype = 'dotted') +
  coord_flip() +
  scale_shape_manual(values = c(13, 17, 17, 17, 17, 16, 16, 16, 15, 15, 15, 15)) +
  scale_colour_manual(values = c('black', 'purple', 'green', '#ffff66', 'red',
                                 'green', '#ffff66', 'red', 
                                 'green', '#ffff66', 'pink')) +
  guides(fill = guide_legend(order = 2), shape = guide_legend(override.aes = list(size = 3)))

只要数据以相同的方式映射,它们就会以与您最初拥有的方式相同的方式出现在图例中。另请注意,对于 geom_point(),无需在 aes() 中再次包含 x 和 y。您可以在此处指定,但如果不指定,该函数将查找 globally-defined 映射(即 ggplot(aes(...)) 内的映射。