0

From this other Q&A, I have managed to create a bar chart with multiple color palettes

enter image description here

Question: how to create a custom legend that prints the 3 color palettes as 4x3 matrix, with at least the row names (number of cylinders), like this:

library(tidyr)

 purples %>% full_join(reds) %>% full_join(blues) %>% spread(manufacturer, colr)

# A tibble: 4 x 4
    cyl    audi    ford    <NA>
* <int>   <chr>   <chr>   <chr>
1     4 #FEE5D9 #EFF3FF #F2F0F7
2     5 #FCAE91 #BDD7E7 #CBC9E2
3     6 #FB6A4A #6BAED6 #9E9AC8
4     8 #CB181D #2171B5 #6A51A3

but then with the color codes replaced by nice legend color boxes. Somewhat related is this Q&A, but then with the legends in a grid, instead of above each other.

Community
  • 1
  • 1
TemplateRex
  • 69,038
  • 19
  • 164
  • 304
  • Should it be `mm <- dd %>%` rather than `mm <- gg_dd %>%` in your example? – eipi10 Aug 26 '16 at 18:57
  • Sorry, wrong link to the `tableGrob` alternative above.Try [**here**](http://stackoverflow.com/questions/18414001/gridextra-colour-different-rows-with-tablegrob) instead. As I wrote, this _might_ be easier than hacking legends. – Henrik Aug 26 '16 at 19:18
  • Please `dput` your "tibble" (or rather data.frame version of it, to avoid loading unnecessary packages). – Henrik Aug 26 '16 at 19:22
  • 1
    You may also melt your "tibble", and use `geom_tile` to make a "heatmap" of your colors. – Henrik Aug 26 '16 at 19:27
  • 1
    I think the `geom_tile` idea would look a bit like the legend made in [this answer](http://stackoverflow.com/a/39046977/2461552) – aosmith Aug 26 '16 at 19:41

1 Answers1

1

Full working solution:

library(dplyr)
library(ggplot2)
library(gridExtra)
library(RColorBrewer)
library(tidyr)

cyl <- sort(unique(mpg$cyl))
ncat <- length(cyl)          # 4 types of cylinders

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

# create palettes
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)

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

gg_dd <- rbind(dd_p, dd_r, dd_b) %>%
        left_join(mm)

main_plot <- gg_dd %>% 
        ggplot(mapping = aes(x = reorder(manufacturer, mcyl), y = n, fill = colr)) + 
        geom_bar(stat = "identity", position = "fill") +
        coord_flip() +
        scale_fill_identity() 

combined_legend<- purples %>% 
        full_join(reds) %>% 
        full_join(blues) %>%
        mutate(manufacturer = ifelse(is.na(manufacturer), "generic", manufacturer)) %>% ggplot(mapping = aes(y = manufacturer, x = factor(cyl), fill = colr)) + 
        geom_tile() + 
        scale_fill_identity() + 
        coord_fixed()

grid.arrange(main_plot, combined_legend, heights=c(10,2), ncol=1)

enter image description here

TemplateRex
  • 69,038
  • 19
  • 164
  • 304