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
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:
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