简体   繁体   中英

ggplot add horizontal line to grouped categorical data and share legend

Here is some code that makes a categorical bar chart and places a mean line on the chart. The problem is that the legends are separate and I can't figure out how to stick them together. I think I have made a dummy variable in the past and included it in the scale_manual arguments but geom_vline doesn't handle the "fill" mappings. Any ideas?

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(panel.background = element_rect(fill = "white")) +
  theme(legend.background = element_rect(color = "black", fill = "white")) 
  
  

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 资源

One option would be to use only the fill scale and make use of custom key glyph.

  1. Set the color for the geom_hline as an argument instead of mapping on the color aes. Instead map a constant eg "" on the fill aes. A Drawback is that we get a warning.
  2. Add an additional color and label to scale_fill_manual .
  3. To get a line as the key glyph for the geom_hline I make use of a custom key glyph which conditionally on the fill color switches between draw_key_path and the default key glyph for geom_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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM