rggplot2

have a different color scale for violin plot and boxplot of the same data


I am trying to make a violinplot superimposed by a boxplot of the same (grouped data). I create a dummy variable to do this as follows:

x <- matrix(runif(n=1000,0,1),ncol =4 )  
df <- reshape2::melt(x)

df$Var2 <- as.factor(df$Var2)
df$Var3 <- df$Var2

library(ggplot2)
df |>
  ggplot(aes(
    x = Var2,
    y = value,
  )) +
  geom_violin(aes(fill=Var2)) +
  geom_boxplot(width=0.2,aes(fill=Var3))+
  theme_light() +
  geom_hline(yintercept = 0) +
  guides(fill = "none") +
  theme(
    axis.text.x = element_blank(), axis.ticks.x = element_blank(),
    axis.text.y = element_blank(), axis.ticks.y = element_blank(),
  ) +
  labs(x = NULL, y = NULL)

I get: enter image description here

However, I want the boxplots and the violin plots to have two different color scales. For example, the boxes in the boxplots could use the Dark2 colors in RColorBrewer while the violins could use the Set2 palette. How can I do this?


Solution

  • Here is an example of using two fill scales with the ggnewscale package. I'm not sure all the details are exactly as you would like, but it should give you a starting point.

        
        x <- matrix(runif(n=1000,0,1),ncol =4 )  
        df <- reshape2::melt(x)
    
        df$Var2 <- as.factor(df$Var2)
        #df$Var3 <- df$Var2
    
        library(ggplot2)
        library(ggnewscale)
        df |>
          ggplot(aes(
            x = Var2,
            y = value,
          )) +
          geom_hline(yintercept = 0) +
          geom_violin(aes(fill=Var2)) +
          scale_fill_manual(values=c('1'="red", '2'="orange", '3'="green", '4' = "blue"))+
          guides(fill = "none") +
          new_scale_fill() +
          geom_boxplot(width=0.2,aes(fill=Var2))+
          scale_fill_manual(values=c('1'="grey10", '2'="grey30", '3'="grey60", '4' = "grey80")) +
          theme_light() +
          guides(fill = "none") +
          theme(
            axis.text.x = element_blank(), axis.ticks.x = element_blank(),
            axis.text.y = element_blank(), axis.ticks.y = element_blank(),
          ) +
          labs(x = NULL, y = NULL)