rggplot2plotggdist

When having plotted a half-violin plot for 2 conditions in ggplot, how do I change the orientation of only one of the conditions?


For my thesis, I need to plot for 2 conditions [condition; baseline / TUS] the individual data points [value; motor evoked potential] of the data with a half-violin plot next to each condition. The half-violins must be on the outsides of the plotted individual data points. However, I just cannot manage to flip only one of the two violin plots, as it either flips both sides or gives me an error message. I have been stuck on this for quite some time, and even my professor does not know how to do this.

So, the goal is this.

However, this is what I currently have.

My current code is this:

dotplot2 <- ggplot(df2, aes(x = variable, y = value, fill=variable, side=variable))+
  ggdist::stat_halfeye(data=df2,adjust = .4, width = .4, justification = 1.9, point_color = NA, alpha=1, trim=FALSE, outline_bars=FALSE, .width = 0)+ 
  theme_classic()+
  scale_fill_manual(values = c("aquamarine4","aquamarine3"))+ 
  ggtitle(label = "TITLE", subtitle = "SUBTITLE")+                                                                
  xlab("Condition")+                                                                                              
  ylab("MEP amplitude (% baseline)")+
  theme(text=element_text(family = "Helvetica Neue", size = 14),                                                                                                       
        plot.title = element_text(face="bold", hjust=0),
        plot.subtitle = element_text(face="italic", hjust=0),
        axis.title.y = element_text(face="bold"),
        axis.title.x = element_text(face="bold"),
        legend.position="none", # Remove legend
        aspect.ratio = 1 # Make the image square
  )
print(dotplot2)

At last, I found something on the internet that should allow you to change the side when using a different method to create a raincloud plot, but this gives me an error code:

df2 %>%
  mutate(side = c("top", "bottom")) %>%
  ggplot(aes(y = variable, x = value, side = side)) +
  stat_dotsinterval(scale = 2/3) +
  labs(
    title = 'stat_dotsinterval(scale = 2/3)', 
    subtitle = 'aes(xdist = dist_normal(mean, sd), side = c("top","both","bottom"))'
  ) +
  coord_cartesian()

Error:

Error in `mutate()`:
! Problem while computing `side = c("top", "bottom")`.
āœ– `side` must be size 56 or 1, not 2.
Run `rlang::last_error()` to see where the error occurred.

My data frame consists of 3 columns and 56 rows. First row is the participant code, second row is the condition they were in, and the third row is their measured motor evoked potential.

structure(list(pp_code = c("P21", "P22", "P23", "P24", "P25", 
"P26", "P27", "P28", "P29", "P30", "P33", "P34", "P35", "P36", 
"P37", "P38", "P39", "P40", "P41", "P42", "P43", "P46", "P47", 
"P48", "P49", "P50", "P51", "P52", "P21", "P22", "P23", "P24", 
"P25", "P26", "P27", "P28", "P29", "P30", "P33", "P34", "P35", 
"P36", "P37", "P38", "P39", "P40", "P41", "P42", "P43", "P46", 
"P47", "P48", "P49", "P50", "P51", "P52"), variable = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L), levels = c("Baseline", "TUS"), class = "factor"), 
    value = c(0.664980982458333, 1.31685611053742, 1.26908044880806, 
    1.41915734446867, 0.748328672413752, 0.497030979841171, 0.909326002760767, 
    0.538014152709411, 1.05266008840402, 1.13139728409305, 0.859818777463091, 
    0.913082205921871, 0.995476954901111, 0.508263021307005, 
    0.830215645140022, 0.673870582901494, 0.842072812542406, 
    1.14146747568508, 0.924882541106572, 1.30693107991824, 1.10506148637615, 
    0.827719535172543, 1.00853898234339, 0.809357655460875, 0.829652924185394, 
    0.64461952079088, 1.34635849696764, 0.886124869956966, 0.5492415313554, 
    1.29378868450619, 0.510659088901906, 0.78611764833977, 0.595110489019161, 
    0.339866198971191, 0.935952498836413, 0.586588180378172, 
    1.03769588229916, 0.932113431519335, 0.654340600218074, 0.459876957898795, 
    0.981083285996913, 0.56931495321102, 0.42576333104496, 0.64144852037276, 
    0.722814594138774, 0.966937564286216, 0.563325042291394, 
    1.09955327158686, 1.10843930610228, 0.829285007127752, 0.939126193763383, 
    0.620343985347041, 0.441423533953645, 0.518075380238605, 
    0.610050707100955, 0.557103015187721)), row.names = c(NA, 
-56L), class = "data.frame")

Solution

  • Another option is using the geom_violinhalf function from the see package. You could use the argument flip to choose the side of the half violins. Here is a reproducible example:

    library(ggplot2)
    library(dplyr)
    library(see)
    
    df2 %>%
      ggplot(aes(x = variable, y = value, fill = variable)) +
      geom_violinhalf(flip = c(1, 3)) +
      geom_point() +
      geom_line(aes(x = variable, y = value, group = pp_code)) +
      scale_fill_manual(values = c("aquamarine4","aquamarine3")) + 
      labs(
        title = 'Plot 1: Individual amplitude', 
        subtitle = '10W conditions'  
      ) +
      xlab("Condition")+                                                                                              
      ylab("MEP amplitude (% baseline)")+
      theme(text=element_text(family = "Helvetica Neue", size = 14),                                                                                                       
            plot.title = element_text(face="bold", hjust=0),
            plot.subtitle = element_text(face="italic", hjust=0),
            axis.title.y = element_text(face="bold"),
            axis.title.x = element_text(face="bold"),
            legend.position="none", # Remove legend
            aspect.ratio = 1 # Make the image square
      ) +
      theme_classic()
    

    Created on 2022-10-14 with reprex v2.0.2