Search code examples
rggplot2geom-segment

geom_segment line vertical for multiple variable plot


The plot code below makes the segment line congverge at the center of the descrete x variable for all colours. What can be done so that the segment line is vertical for each x variable respective of colour?

#~ Plot data
ggplot(data = data0, aes(x = v3, y = v4)) +
  geom_point(aes(colour = v2),
             size = 2,
             alpha = .25,
             position = position_jitterdodge(jitter.width = 0.15, seed = 1)
  ) +
  stat_summary(fun = mean, geom = "point", size = 5, aes(colour = v2), position = position_dodge(0.75)) +
  geom_segment(data = data1, aes(x = v3, xend = v3, y = v4, yend = grand_mean, colour = v2), 
               size = 1, position = position_dodge(width = 0.75)) +
  geom_hline(data = data1, aes(yintercept = grand_mean)) +
  facet_wrap(facets = vars(v1)) +
  theme_bw()

multivariable plot

DATA:

#~ Raw data
data0 <- data.frame(v1 = sample(c("foo", "bar"), 1000, replace = TRUE),
                    v2 = sample(letters[1:4], 1000 , replace = TRUE),
                    v3 = sample(1:4, 1000, replace = TRUE),
                    v4 = rnorm(1000))

#~ Summary data
data1 <- data0 %>%
  group_by(v1, v2, v3) %>%
  summarise(v4 = mean(v4))
data1$grand_mean <- mean(data0$v4)

Solution

  • position_dodge() can't handle xend and yend. Use geom_line() or geom_linerange() instead:

    ggplot(data = data0, aes(x = v3, y = v4)) +
      geom_point(aes(colour = v2),
                 size = 2,
                 alpha = .25,
                 position = position_jitterdodge(jitter.width = 0.15, seed = 1)
      ) +
      stat_summary(fun = mean, geom = "point", size = 5, aes(colour = v2), position = position_dodge(0.75)) +
      geom_linerange(data = data1, aes(x = v3, ymin = v4, ymax = grand_mean, colour = v2), 
                   size = 1, position = position_dodge(width = 0.75)) +
      geom_hline(data = data1, aes(yintercept = grand_mean)) +
      facet_wrap(facets = vars(v1)) +
      theme_bw()