1

I am trying to create a plot in ggplot2 similar to this one: enter image description here

Here is the code I am using:

Dataset %>% 
  group_by(Participant, Group, Emotion) %>%
  ggplot(aes(y = Score, x = Emotion, fill = Group, colour = Group)) +
  geom_flat_violin(position = position_nudge(x = .2, y = 0), alpha = .4) +
  geom_point(aes(y = Score, color = Group), position = position_jitter(width = .15), size = 3, alpha = 0.4) +
  stat_summary(aes(y = Score, group = Emotion), fun.y = mean, geom="line", size = 2.2, alpha = 1.2, width = 0.25, colour = 'gray48') +
  stat_summary(fun = mean, geom = 'pointrange', width = 0.2, size = 2, alpha = 1.2, position=position_dodge(width=0.3)) +
  stat_summary(fun.data = mean_se, geom='errorbar', width = 0.25, size = 2.2, alpha = 1.2, linetype = "solid",position=position_dodge(width=0.3)) +
  guides(color = FALSE) +
  scale_color_brewer(palette = "Dark2") +
  scale_fill_brewer(palette = "Dark2") +
  ylim(0, 100) +
  graph_theme

What I am failing to do is set up the stat_summary(geom = 'line') to connect the green and orange means within each emotion on the x-axis. Could anyone give any pointers on this? I'd also like all the other features to stay the same if possible (e.g., I wouldn't like to use facet_grid or facet_wrap).

Thank you!

When I change the group argument in stat_summary to 'Group' instead of 'Emotion', means for each group are connected across emotions, but I can't figure out how to connect means of different groups within each emotion: enter image description here

Joseph K.
  • 57
  • 5

2 Answers2

0

This is a tricky one because your line needs to connect points that have different x values but even if you jitter in the point layer, they still technically have the same x value so the line doesn't know how to connect them. What others have done is to manually add the jitter to force the points to have a different x position. For more inspiration check out this, this and this. Here's an example:

library(tidyverse)

set.seed(1)

emotion <- c("anger", "fear", "sadness")
group <- letters[1:2]
participant <- 1:10

dat <- expand_grid(emotion, group, participant) %>% 
  mutate(across(everything(), as.factor),
         score = sample(x = 1:100, size = nrow(.), replace = T))


dat %>% 
  mutate(new_emot = case_when(
    group == "a" ~as.numeric(emotion) - 0.125,
    group == "b" ~as.numeric(emotion) + 0.125
  )) %>% 
  ggplot(aes(x = emotion, y = score)) +
  stat_summary(aes(color = group), fun = mean, geom = "point", position = position_dodge(width = 0.5)) +
  stat_summary(aes(color = group), fun.data = mean_se, geom = "errorbar", width = 0.5, position = position_dodge(width = 0.5)) +
  stat_summary(aes(x = new_emot, group = emotion), fun = mean, geom = "line") +
  theme_bw()

Created on 2021-03-24 by the reprex package (v1.0.0)

Dan Adams
  • 4,971
  • 9
  • 28
0

Setting geom_line to the same position as pointrange and errorbar will solve the problem. i.e.,

stat_summary(aes(y = Score, group = Emotion), fun.y = mean, geom="line", size = 2.2, alpha = 1.2, width = 0.25, colour = 'gray48', position=position_dodge(width=0.3))