Search code examples
rggplot2colorsscalefill

Modifying the colors with commands scale_fill_manual() and scal_fill_discrete() on a ggplot2 histogram


My data frame (df) consists of two columns, one with random values (continuous measurements) and another with three levels (c1, c2, c3):

df <- data.frame(col1= round(rnorm(150),2),col2 =       c(rep("c1",times=50),rep("c2",times=50),rep("c3",times=50)))

My ggplot code looks like that:

library(ggplot2)

ggplot(df) +

geom_histogram(aes(x = col1, fill = col2),
             position = "stack",col="black", bins = 30, alpha = 0.6) +

scale_fill_manual(values = c("steelblue1", "yellow", "darkolivegreen2"),breaks = c("c1", "c2", "c3")) +

scale_fill_discrete("Factor", labels = c(expression(italic("c1")), 
                                         expression(italic("c2")),
                                         expression(italic("c3")))) +

theme_classic()

The colours that I define in scale_fill_manual() do not actually correspond to the colors in the histogram. It seems that it is an issue with the two arguments scale_fill_manual() and scale_fill_discrete() as it appears this message:

Scale for fill is already present. Adding another scale for fill, which will replace the existing scale.

How can I specify the colors for each level?

I've tried with the possible solutions that are already in here but nothing happens.


Solution

  • In vanilla ggplot2 you can have only one scale per aesthetic, i.e. adding the scale_fill_discrete will overwrite (or drop) the scale_fill_manual. But you could simply set your labels and or names via scale_fill_manual:

    Note: If you just want to change the font face of the legend labels there is no need to use expression. You could do so using + theme(legend.text = element_text(face = "italic")).

    set.seed(123)
    
    df <- data.frame(
      col1 = round(rnorm(150), 2),
      col2 = c(rep("c1", times = 50), rep("c2", times = 50), rep("c3", times = 50))
    )
    
    library(ggplot2)
    
    ggplot(df) +
      geom_histogram(aes(x = col1, fill = col2),
        position = "stack", col = "black", bins = 30, alpha = 0.6
      ) +
      scale_fill_manual(
        values = c("steelblue1", "yellow", "darkolivegreen2"),
        breaks = c("c1", "c2", "c3"),
        labels = c(
          expression(italic("c1")),
          expression(italic("c2")),
          expression(italic("c3"))
        ),
        name = "Factor"
      ) +
      theme_classic()