Search code examples
rggplot2violin-plot

Violin plot, adjust vjust differentially for each shape?


I am trying to label my violin plot in ggplot with mean_cl_boot and n values for each violin shape, and wondering if there is a way to adjust vjust differently for each violin shape, or if there is a way to get count values regularly up above the shapes. As you can see my violins have varying lengths, so setting vjust to -8 (for example) puts the labels all over the place relative to the shapes.

enter image description here

I've included my code for the below plot, as well as a reproducible example with iris, but I wanted to get the point across with my weird dataset because iris looks so clean. Sorry I simply haven't found the right search terms for my question but I imagine it is something simple.

# Now make a nicer plot of Known Behavioral Age Categories vs Display Rate 
ggplot(data_changedorderwithoutNAs, aes(x = KnownBehAgeCategories,y = Energetically.Expensive.Displays.Per.Hour)) +
  geom_violin(
    mapping = aes(
      x = KnownBehAgeCategories,
      y = Energetically.Expensive.Displays.Per.Hour, fill = KnownBehAgeCategories
    )
  )+
  theme_classic()+
  stat_summary(fun.data = "mean_cl_boot", geom = "pointrange")+
  stat_summary(fun.data = n_fun, geom = "text", vjust = -6)+
  labs(y="Display Rate", x="Known Behavioral Age")+
  scale_fill_brewer(palette="BuPu")

With the iris dataset:

ggplot(iris, aes(x = Species,y = Petal.Width)) +
  geom_violin(
    mapping = aes(
      x = Species,
      y = Petal.Width, fill = Species
    )
  )+
  theme_classic()+
  stat_summary(fun.data = "mean_cl_boot", geom = "pointrange")+
  stat_summary(fun.data = n_fun, geom = "text", vjust = -8)+
  labs(y="Species", x="Petal Width")+
  scale_fill_brewer(palette="BuPu")

Solution

  • Set vjust to 0, and use n_fun updated version (from this post: Automatic n plotting with ggplot and stat_summary) with y value set to the max:

    n_fun <- function(x){
      return(data.frame(y = max(x), label = paste0("n = ",length(x))))
    } 
    
    ggplot(iris, aes(x = Species,y = Petal.Width,fill = Species)) +
      geom_violin() +
      theme_classic() +
      stat_summary(fun.data = "mean_cl_boot", geom = "pointrange") +
      stat_summary(fun.data = n_fun, geom = "text", vjust = 0) +
      labs(y="Species", x="Petal Width")+
      scale_fill_brewer(palette="BuPu")
    

    enter image description here