rggplot2legendgeom-hline

How to specify geom_hline color AND linetype in ggplot legend?


I'm using hlines to visualize screening level thresholds while displaying four categorical variables and one numeric variable. I want to display both a different linetypes AND color for each threshold hline in the plot and in the legend. I can make the lines different colors and types in the plot, but legend differentiates only linetype and both are the color of the second hline.

library(tidyverse)
library(ggplot2)


# reformat data for SO example; pivot the two mpg columns into one
mpg_lngr <-mpg %>% 
  pivot_longer(cols = c(cty, hwy), names_to="road",values_to= "mpg") 

ggplot(mpg_lngr, aes(x=manufacturer, y=mpg))+
  #add hlines first so they are in the back of the plot
  geom_hline(aes(linetype = "gas guzzler", yintercept=12),color = "#d95f02") +
  geom_hline(aes(linetype = "awesome",yintercept=27),color = "#1b9e77")+
  geom_point(aes(color = as.factor(year), 
                  shape = road))+
  scale_shape_manual(values = c("cty" = 2, 
                                "hwy" = 17)) + 
  scale_y_continuous(name="miles per gallon")+
  scale_color_manual(values=c("1999"="#e7298a", "2008"="#7570b3"))+
  scale_linetype_manual(values = c("solid","dotted")) + 
  guides(color=guide_legend(title="year"), 
         shape = guide_legend(title = "usage"),
         linetype = guide_legend(title = "efficiency screening level")) +
  theme(axis.text.x=element_text(angle=90, hjust = 1, vjust = 0.25))+
  facet_wrap(~drv, scales = "free_x") 

Created on 2023-03-29 with reprex v2.0.2

I've tried moving color= into the hline aes() call, but then everything is just black. I tried adding "gas guzzler" = "#d95f02", "awesome" = "#1b9e77" to the scale_color_manual() with color= in the hline aes() (i.e., throwing spaghetti on the wall at this point.). I do want to keep facet wrap in the mix because it best replicates what I'm trying to visualize with my data set. The issue seems to be that I am using geom_hline and the values are not a part of the data set. Thank you for any solutions/suggestions that resolve this issue.


Solution

  • You could fix your issue by setting the colors for the legend using the override.aes argument of guide_legend:

    library(tidyverse)
    
    mpg_lngr <- mpg %>%
      pivot_longer(cols = c(cty, hwy), names_to = "road", values_to = "mpg")
    
    ggplot(mpg_lngr, aes(x = manufacturer, y = mpg)) +
      geom_hline(aes(linetype = "gas guzzler", yintercept = 12), color = "#d95f02") +
      geom_hline(aes(linetype = "awesome", yintercept = 27), color = "#1b9e77") +
      geom_point(aes(
        color = as.factor(year),
        shape = road
      )) +
      scale_shape_manual(values = c(
        "cty" = 2,
        "hwy" = 17
      )) +
      scale_y_continuous(name = "miles per gallon") +
      scale_color_manual(values = c("1999" = "#e7298a", "2008" = "#7570b3")) +
      scale_linetype_manual(values = c("solid", "dotted")) +
      guides(
        color = guide_legend(title = "year"),
        shape = guide_legend(title = "usage"),
        linetype = guide_legend(
          title = "efficiency screening level",
          override.aes = list(color = c("#1b9e77", "#d95f02"))
        )
      ) +
      theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.25)) +
      facet_wrap(~drv, scales = "free_x")