I am trying to get my ggplot2 legends to sit together well.
I have a fill legend and a colour legend and I want them to be over multiple rows at the base of the plot but with the colour legend continuing directly after the fill legend, rather than starting a new column.
I've made a quick example and desired output (just made in paint) below to illustrate
library(ggplot2)
set.seed(1)
testdf <- data.frame(mon = factor(month.abb, levels = month.abb), y = rnorm(84,mean = 20, sd = 10), cat = rep(paste0("class ",letters[1:7]), each = 12))
thresholds <- data.frame(ThresholdNm = c("low","high"), ThresholdVal = c(110,150))
ggplot(testdf, aes(x = mon, y = y, fill = cat))
geom_bar(stat = "identity")
geom_hline(data = thresholds, aes(yintercept = ThresholdVal, colour = ThresholdNm))
scale_colour_manual(values = c("red","black"))
theme(legend.position = "bottom", legend.title = element_blank())
guides(fill = guide_legend(nrow=3,byrow=FALSE,order = 1),colour = guide_legend(nrow=2,byrow=FALSE,order = 2))
This is what I get:
But what I am hoping for is this:
Created on 2022-11-10 by the reprex package (v0.3.0)
CodePudding user response:
Adapting my answer on this post to your case you could achieve your desired result using a custom key glyph like so:
- Basically this involves mapping
ThresholdVal
on thefill
aes ingeom_hline
. Doing so will add the items to the fill legend too. - Create a color palette which could be used for both the
fill
and thecolor
scale and which takes care of the right order of the items. - Write custom key glyph function which conditional on the color value switches between the key glyph used for bars and the one used for
geom_hline
- Remove the color legend.
- Use theme options to get a border around all legend keys including the ones for the hlines.
library(ggplot2)
nclass <- nlevels(factor(testdf$cat))
pal <- c(scales::hue_pal()(nclass), "red", "black")
names(pal) <- c(levels(factor(testdf$cat)), "high", "low")
draw_key_cust <- function(data, params, size) {
if (data$fill %in% c("red", "black")) {
data$colour <- data$fill
data$fill <- NA
draw_key_path(data, params, size)
} else {
GeomCol$draw_key(data, params, size)
}
}
ggplot(testdf, aes(x = mon, y = y, fill = cat))
geom_bar(stat = "identity", key_glyph = "cust")
geom_hline(data = thresholds, aes(yintercept = ThresholdVal, colour = ThresholdNm, fill = ThresholdNm))
scale_fill_manual(values = pal, aesthetics = c("fill", "color"))
theme(legend.position = "bottom", legend.title = element_blank(),
legend.key = element_rect(linewidth = .25 * .pt, color = "white"))
guides(fill = guide_legend(nrow = 3, byrow = FALSE, order = 1), colour = "none")
#> Warning in geom_hline(data = thresholds, aes(yintercept = ThresholdVal, :
#> Ignoring unknown aesthetics: fill