Home > Software engineering >  Customize ggplot2 legend with different variables
Customize ggplot2 legend with different variables

Time:05-29

I have the following data about American and German teenagers' coding skills. I can easily display their bar plots, but I need to present the total number of teenagers from each country as well.

DF <- data.frame(code = rep(c("A","B","C"), each = 2),
                 Freq = c(441,121,700,866,45,95),
                 Country = rep(c("USA","Germany"),3),
                 Total = rep(c(1186,1082),3))  

ggplot(DF, aes(code, Freq, fill = code))   geom_bar(stat = "identity", alpha = 0.7)   
  facet_wrap(~Country, scales = "free")  
  theme_bw()  
  theme(legend.position="none") 

For example, instead of presenting the default legend for the code, I could replace it with the Country and the Total. Your help is appreciated

CodePudding user response:

Here's what I would suggest:

library(dplyr); library(ggplot2)
DF %>%
  add_count(Country, wt = Total) %>%
  mutate(Country_total = paste0(Country, ": Total=", n)) %>%
  ggplot(aes(code, Freq, fill = code))   geom_bar(stat = "identity", alpha = 0.7)   
    facet_wrap(~Country_total, scales = "free")  
    theme_bw()  
    theme(legend.position="none") 

enter image description here

To do what you're requesting would take a different approach, since the data you're describing would not strictly be a ggplot2 legend (which explains how one of the variables is mapped to one of the graph aesthetics), rather it would be a table or annotation that is displayed alongside the plot. This could be generated separately and added to the figure using patchwork or grid packages.

For instance:

library(patchwork); library(gridExtra)
ggplot(DF, aes(code, Freq, fill = code))   geom_bar(stat = "identity", alpha = 0.7)   
  facet_wrap(~Country, scales = "free")  
  theme_bw()  
  theme(legend.position="none")  
  tableGrob(count(DF, Country, wt = Total))  
  plot_layout(widths = c(2,1))

enter image description here

  • Related