'Divide Legend by multiple groups
In am looking a solution to a different representation of the legend to the example given here: https://rpubs.com/ageek/ggplot-adv-part2
The code below gives the following graph:
ggplot(mpg, aes(manufacturer))+
geom_bar(aes(fill=class), width = 0.5)+
theme(axis.text.x = element_text(angle=65, vjust=0.6))
Is there a way to represent the legend in groups for each different value of the variable x (discrete) given in x axis? For example, in the above example the legend for the first two entries in the x axis (Audi and Chevrolet) would look as following:
In the desired outcome, all entries in x axis should be included in the legend, and dynamically change in case the legend is adjusted (e.g. Audi removed or a new brand is added)
Solution 1:[1]
This is not too difficult with a mix of patchwork and cowplot. My answer is just to show the technical feasibility - I do not endorse this type of visualisation and I totally agree with Allan. To consider: You present the manufacturer/class relation already in the main plot - Your legend design would duplicate this!
library(dplyr)
library(ggplot2)
library(cowplot)
library(patchwork)
## named vector so you get the correct color mapping
class_colors <- setNames(scales::hue_pal()(length(unique(mpg$class))), sort(unique(mpg$class)))
p <-
ggplot(mpg, aes(manufacturer)) +
geom_bar(aes(fill = class), width = 0.5) +
theme(
axis.text.x = element_text(angle = 65, vjust = 0.6),
## remove legend
legend.position = "none"
) +
## for better control use the same colors in the main plot
scale_fill_manual(values = class_colors)
## split by your categorising variable and loop a plot over it
ls_man <- mpg %>%
split(.$manufacturer)
## I'm looping over an index so I can dynamically change legend title and breaks
ls_plots <- lapply(1:length(ls_man), function(i) {
ggplot(ls_man[[i]], aes(manufacturer)) +
geom_bar(aes(fill = class), width = 0.5) +
theme(axis.text.x = element_text(angle = 65, vjust = 0.6)) +
labs(fill = names(ls_man)[i]) +
scale_fill_manual(values = class_colors, breaks = unique(ls_man[[i]]$class))
})
## create the legends with patchwork and cowplot
p_mess <- wrap_plots(ls_plots) + plot_layout(guides = "collect")
p_leg <- get_legend(p_mess)
## draw the final plot with cowplot
ggdraw(plot_grid(p, p_leg))
The legends are all there, but it's just so messy you cannot see them because of the small size of this device.
Created on 2022-05-06 by the reprex package (v2.0.1)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |