I am creating a scatter plot using ggplot2
with three groups. I am then adding an additional layer to plot additional data. In both cases, I map the data to group, but in the second case I want to legend to be dissociated from groups and just be a binary black and white linetype legend. Right now the legend merges everything.
Based on other solutions, I've tried scale_linetype_identity()
and scale_linetype_manual()
, to no avail.
Reprex:
library(ggplot2)
# Data 1
data1 <- data.frame(
x = c(1, 2, 3),
y = c(10, 20, 20, 10, 15, 15, 10, 10, 10),
group = factor(c(rep("A", 3), rep("B", 3), rep("C", 3)),
levels = c("A", "B", "C")))
# Plot 1
p <- ggplot(data1, aes(x = x, y = y, color = group, shape = group)) +
geom_line(show.legend = FALSE) +
geom_point()
p
# Data 2
data2 <- data.frame(
x = c(1, 2),
y = c(10, 19.3, 10, 12.5, 10, 7.5),
group = data1$group[-c(3, 6, 9)],
condition = c("Y", "Z")
)
p +
geom_line(data = data2, aes(x = x, y = y, color = group),
linetype = "dotted", show.legend = TRUE) +
geom_point(data = data2)
Created on 2024-09-15 with reprex v2.1.1
And I'm trying to get this legend:
But without the linetype for the group legend, only the shape.
Before plotting, combine the data sets for each condition, using an id
variable to track the source. Then you can map this new column to the linetype
aesthetic, getting you most of the way towards the legend you describe. To remove the lines from the color legend you can override the aesthetics. linetype = 0
is a blank line.
library(ggplot2)
library(dplyr)
data1 <- data.frame(
x = c(1, 2, 3),
y = c(10, 20, 20, 10, 15, 15, 10, 10, 10),
group = factor(c(rep("A", 3), rep("B", 3), rep("C", 3)),
levels = c("A", "B", "C")))
data2 <- data.frame(
x = c(1, 2),
y = c(10, 19.3, 10, 12.5, 10, 7.5),
group = data1$group[-c(3, 6, 9)]
)
bind_rows(data1, data2, .id = 'condition') |>
ggplot(aes(x = x, y = y, color = group, shape = group, linetype = condition)) +
geom_point() +
geom_line() +
guides(color = guide_legend(override.aes = list(linetype = 0)))