Search code examples
rggplot2violin-plot

ggplot not respectig order of colours in scale_fill_manual()?


I am creating some violin plots and want to colour them. It works for a matrix of dimension 9, as in my previous question

ggplot violin plot, specify different colours by group?

but when I increase the dimension to 15, the order of the colours are not respected. Why is this happening?

Here it works (9 columns):

library(ggplot2)
dat <- matrix(rnorm(250*9),ncol=9)

# Violin plots for columns
mat <- reshape2::melt(data.frame(dat), id.vars = NULL)

mat$variable_grouping <- as.character(sort(rep(1:9,250)))



pp <- ggplot(mat, aes(x = variable, y = value, fill = variable_grouping)) + 
  geom_violin(scale="width",adjust = 1,width = 0.5)  + scale_fill_manual(values=rep(c("red","green","blue"),3))
pp

Here it does not work (15 columns):

library(ggplot2)
dat <- matrix(rnorm(250*15),ncol=15)

# Violin plots for columns
mat <- reshape2::melt(data.frame(dat), id.vars = NULL)

mat$variable_grouping <- as.character(sort(rep(1:15,250)))



pp <- ggplot(mat, aes(x = variable, y = value, fill = variable_grouping)) + 
  geom_violin(scale="width",adjust = 1,width = 0.5)  + scale_fill_manual(values=rep(c("red","green","blue"),5))
pp

Solution

  • This is related to setting factor levels. Since variable_grouping is a character, ggplot2 converts it to a factor for plotting. It uses the default factor order, where 1 always comes before 2. So in your example 11-15 all come before 2 in the legend.

    You can manually set the factor order to avoid the default order. I use forcats::fct_inorder() for this because it's convenient in this case where you want the order of the factor to match the order of the variable. Note you can also use factor() directly and set the level order via the levels argument.

    ggplot(mat, aes(x = variable, y = value, fill = forcats::fct_inorder(variable_grouping))) + 
         geom_violin(scale="width", adjust = 1, width = 0.5)  + 
         scale_fill_manual(values=rep(c("red","green","blue"),5)