ggplot add horizontal line to grouped categorical data and share legend
One option would be to use only the fill
scale and make use of custom key glyph.
- Set the color for the
geom_hline
as an argument instead of mapping on thecolor
aes. Instead map a constant e.g.""
on thefill
aes. A Drawback is that we get a warning. - Add an additional color and label to
scale_fill_manual
. - To get a line as the key glyph for the
geom_hline
I make use of a custom key glyph which conditionally on thefill
color switches betweendraw_key_path
and the default key glyph forgeom_col
. To make this work I use a"red2"
as the additional fill color for the hline which I switch to"red"
inside the custom key glyph function.
library(tidyverse)
data(mtcars)
y = mean(mtcars$mpg)
x = unique(mtcars$cyl)
meanDf <- data.frame(x, y )
mtcars$mean = y
mtcars$group = "mean"
draw_key_cust <- function(data, params, size) {
if (data$fill %in% c("red2")){
data$colour <- "red"
data$fill <- NA
draw_key_path(data, params, size)
} else
GeomCol$draw_key(data, params, size)
}
mtcars %>%
ggplot(aes(x = factor(cyl), y = mpg, fill = factor(carb))) +
geom_hline(data = meanDf, aes(yintercept = y, fill = ""), color = "red") +
geom_col(key_glyph = "cust") +
scale_fill_manual(name = NULL, values = c("red2", "blue", "red", "green", "white", "black", "yellow"), labels = c("label", paste("myLabel", 1:6))) +
theme(panel.background = element_rect(fill = "white")) +
theme(legend.background = element_rect(color = "black", fill = "white"))
#> Warning: Ignoring unknown aesthetics: fill
I think for readability, it's better to separate them out. However, for formatting purpose, you sure can bring them as close as you want by dropping the legend.title
(not just assigning it an empty string) and adjusting the legend.margin
and legned.spacing
. For instance,
library(tidyverse)
data(mtcars)
y = mean(mtcars$mpg)
x = unique(mtcars$cyl)
meanDf <-
data.frame(x, y )
mtcars$mean = y
mtcars$group = "mean"
mtcars %>%
ggplot(aes(x = factor(cyl), y = mpg, fill = factor(carb))) +
geom_col(position = "dodge") +
geom_hline(data = meanDf, aes(yintercept = y, color = "")) +
scale_fill_manual(name = "", values = c("blue", "red", "green", "white", "black", "yellow"), labels = paste("myLabel", 1:6)) +
scale_color_manual(name = "", values = "red", label = "myLabel") +
theme(
legend.title = element_blank(),
legend.margin = margin(t = 0, b = 0, r = 2, l = 2),
legend.spacing.y = unit(.5, "pt")
)
Output