Home > Mobile >  Adding 2 vlines to a ggplot, with an additional custom legend for the lines
Adding 2 vlines to a ggplot, with an additional custom legend for the lines

Time:12-02

I'm trying to have a ggplot with two vertical lines on it, with a separate custom legend to explain what the lines represent. This is my code (using iris):

irate <- as.data.frame(iris)
irate$Species <- as.character(irate$Species)

irritating <- ggplot(irate)  
  geom_line(aes(y = Sepal.Length, x = Sepal.Width), color = "blue")  
  geom_point(aes(y = Sepal.Length, x = Sepal.Width, color = Species), size = 5)  
  theme(legend.position = "right", axis.text.y = element_blank(), axis.title.y = element_blank(), axis.ticks.y = element_blank(), panel.grid.major.y = element_blank()) 
  labs(title = "The chart", x = "Sepal Width")  
  geom_vline(color = "black", linetype = "dashed", aes(xintercept = 3)) 
  geom_vline(color = "purple", linetype = "dashed", aes(xintercept = 4))

irritating 

Result

I've tried using things like scale_color_manual (etc), but for some reason when doing so it will interfere with the main legend and not produce a separate one.

Using answers to questions like: enter image description here

CodePudding user response:

One option to achieve your desired result would be to use a different aesthetic to create the colro legend for your vlines. In my code below I map on the linetype aes and use the override.aes argument of guide_legend to assign the right colors:

irate <- as.data.frame(iris)
irate$Species <- as.character(irate$Species)

library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 4.2.2

base <- ggplot(irate)  
  geom_line(aes(y = Sepal.Length, x = Sepal.Width), color = "white")  
  geom_point(aes(y = Sepal.Length, x = Sepal.Width, color = Species), size = 5)  
  theme(legend.position = "right", axis.text.y = element_blank(), axis.title.y = element_blank(), axis.ticks.y = element_blank(), panel.grid.major.y = element_blank()) 
  labs(title = "The chart", x = "Sepal Width") 

base  
  geom_vline(color = "black", aes(xintercept = 3, linetype = "Black Line")) 
  geom_vline(color = "purple", aes(xintercept = 4, linetype  = "Purple line"))  
  scale_linetype_manual(name = "still problematic", values = c("dashed", "dashed"))  
  guides(linetype = guide_legend(override.aes = list(color = c("black", "purple"))))

And the second and perhaps cleaner solution would be to use the ggnewscale package which allows to have multiple legends for the same aesthetic:


library(ggnewscale)

base  
  new_scale_color()  
  geom_vline(linetype = "dashed", aes(xintercept = 3, color = "Black Line")) 
  geom_vline(linetype = "dashed", aes(xintercept = 4, color  = "Purple line"))  
  scale_color_manual(name = "still problematic", values = c("black", "purple"))

CodePudding user response:

Here is a way with package ggnewscale that makes plotting two legends for two color mappings very easy.
The main trick is to create a data.frame with the x intercept values and colors, then assign this data set to the data argument of geom_vline. If this is run after new_scale_color() the colors will be the right ones.

library(ggplot2)
library(ggnewscale)

irate <- iris
irate$Species <- as.character(irate$Species)
happy <- data.frame(xintercept = c(3, 4), color = c("black", "purple"))

delightful <- ggplot(irate)  
  geom_line(aes(y = Sepal.Length, x = Sepal.Width), color = "blue")  
  geom_point(aes(y = Sepal.Length, x = Sepal.Width, color = Species), size = 5)  
  theme(legend.position = "right", axis.text.y = element_blank(), axis.title.y = element_blank(), axis.ticks.y = element_blank(), panel.grid.major.y = element_blank()) 
  labs(title = "The chart", x = "Sepal Width")  
  new_scale_color()  
  geom_vline(
    data = happy,
    mapping = aes(xintercept = xintercept, color = color),
    linetype = "dashed"
  )  
  scale_color_manual(values = c(black = "black", purple = "purple"))

delightful 

Created on 2022-11-30 with reprex v2.0.2

CodePudding user response:

Using linetype in aes to put those parts in the legend you can then override the guide display colours:

library(ggplot2)

irate <- as.data.frame(iris)
irate$Species <- as.character(irate$Species)

irritating <- ggplot(irate)  
  geom_line(aes(y = Sepal.Length, x = Sepal.Width), color = "white")  
  geom_point(aes(y = Sepal.Length, x = Sepal.Width, color = Species), size = 5)  
  theme(
    legend.position = "right",
    axis.text.y = element_blank(),
    axis.title.y = element_blank(),
    axis.ticks.y = element_blank(),
    panel.grid.major.y = element_blank()
  )  
  labs(title = "The chart", x = "Sepal Width")  
  geom_vline(linewidth = 1.5,
             color = "black",
             aes(xintercept = 3, linetype = "Something"))  
  geom_vline(linewidth = 1.5,
             color = "purple",
             aes(xintercept = 4, linetype = "Another thing"))  
  scale_linetype_manual(
    "Things",
    values = c("dashed", "dashed"),
    guide = guide_legend(override.aes = list(colour = c("purple", "black")))
  )

irritating

  • Related