Search code examples
rggplot2customizationgeom-barcolor-palette

How to create custom color palette to be used by scale_fill_manual()


Consider the following code that makes a bar chart with a purple color palette

library(dplyr)
library(ggplot2)

dd <- mpg %>% 
        group_by(manufacturer, cyl) %>% 
        summarise(n = n()) %>%
        ungroup() 

mm <- dd %>%
        group_by(manufacturer) %>%
        summarise(mcyl = weighted.mean(cyl, n)) %>%
        arrange(mcyl) %>%
        ungroup()

dd %>% left_join(mm) %>%
        ggplot(mapping = aes(x = reorder(manufacturer, mcyl), y = n, fill = factor(cyl))) + 
        geom_bar(stat = "identity", position = "fill") +
        coord_flip() +
        scale_fill_brewer(palette = "Purples")

enter image description here

Question: How can I make the palette for Audi red ("Reds") and for Ford blue ("Blues"), while keeping the others purple ("Purples")?

What is the most convenient (preferably tidyverse) way to put these red/blue/purple palettes in a variable and passing it to scale_fill_manual() (as explained in this related Q&A)?


Solution

  • Full working solution:

    cyl <- sort(unique(mpg$cyl))
    ncat <- length(cyl)          # 4 types of cylinders
    
    # create palettes
    library(RColorBrewer)
    purples <- tibble(cyl, colr = brewer.pal(ncat, "Purples"))
    reds    <- tibble(manufacturer = "audi", cyl, colr = brewer.pal(ncat, "Reds"))
    blues   <- tibble(manufacturer = "ford", cyl, colr = brewer.pal(ncat, "Blues"))
    
    # merge them with the data
    dd_p <- dd %>% filter(!(manufacturer %in% c("audi", "ford"))) %>% left_join(purples)
    dd_r <- dd %>% filter(manufacturer == "audi") %>% left_join(reds)
    dd_b <- dd %>% filter(manufacturer == "ford") %>% left_join(blues)
    
    gg_dd <- rbind(dd_p, dd_r, dd_b) %>%
            left_join(mm)
    
    gg_dd %>% 
            ggplot(mapping = aes(x = reorder(manufacturer, mcyl), y = n, fill = colr)) + 
            geom_bar(stat = "identity", position = "fill") +
            coord_flip() +
            scale_fill_identity() 
    

    enter image description here