Reputation: 33
Here is a data.frame with three subjects in a 2 by 2 design:
x<-data.frame("sub" = rep(c("sub1","sub2","sub3"),times=4),
"cond1" = rep(c("A","B"),times=c(6,6)),
"cond2" = rep(c("C","C","C","D","D","D"),times=2),
"score" = c(6,5,4, 5,4,3, 4,3,2, 3,2,1))
Here is the split violin plot (for function, https://gist.github.com/Karel-Kroeze/746685f5613e01ba820a31e57f87ec87):
dodge <- position_dodge(width=.5)
ggplot(x, aes(x=cond1, y=score, fill=cond2))+
geom_split_violin(trim = F)+
geom_point(shape=16,position=dodge)
What I would like to do is connect the individual subject scatter points with a line across the fill condition (e.g., sub1 in cond1 A and cond2 C will connect to sub1 in cond1 A and cond2 D). Does anyone know if this is possible?
Upvotes: 3
Views: 1147
Reputation: 66415
Here's an approach. First, I spread
the table so the beginning and end of geom_segment
can be based on different columns. Then I convert the cond1
values to numeric (which is what ggplot does under the hood) and feed those into the x fields. The x dodge offset of 0.12 was manual, but there's probably a clever way (beyond my current understanding) to use the ggplot settings to determine that automatically.
library(tidyverse)
dodge <- position_dodge(width=.5)
ggplot(x, aes(x=cond1, y=score, fill=cond2))+
geom_split_violin(trim = F)+
geom_point(shape=16,position=dodge) +
geom_segment(data = x %>% spread(cond2, score),
aes(x = as.numeric(cond1) - 0.12,
xend = as.numeric(cond1) + 0.12,
y = C, yend = D), inherit.aes = FALSE, color = "black")
Upvotes: 3