I am trying to create a ggplot map which includes two simple feature line datasets. I would like the lines to either appear in the same legend, or a separate legend. However the approach I am taking results in a mismatch between the plot colours and the legend colours.
Here is a simple example that shows the problem.
library("sf")
library("sfheaders")
library("ggplot2")
df1 <- data.frame(
x = c(0,1,0,1,0,1),
y = c(1,1,2,2,3,3),
id = c("A","A","B","B","D","D")
)
df2 <- data.frame(
x = c(0,1),
y = c(4,4),
id= c("C","C")
)
set1_sf <- sfheaders::sf_linestring(
obj = df1, x = "x", y = "y", linestring_id = "id"
)
set2_sf <- sfheaders::sf_linestring(
obj = df2, x = "x", y = "y", linestring_id = "id"
)
palette <- c("#7FC97F","#BEAED4","#FDC086")
ggplot() +
geom_sf(set1_sf, mapping=aes(colour=id), lwd=0.8) +
geom_sf(set2_sf, mapping=aes(colour=id), lwd=0.8) +
scale_colour_manual(name="Lines",
values = c(palette,"black"),
labels = c(set1_sf$id, set2_sf$id))
With this result:
In the legend of the output plot, lines A, B and D are correctly coloured with the palette colours, and line C in black. However on the plot itself, the colours of D and C are incorrectly swapped.
If I change the id value in df2 to "X" the plot colours appear correctly.
What am I doing wrong? Is there a better way?
One way to return your desired outcome is to use breaks =
to explicitly reorder the legend keys:
library(ggplot2)
# Legend order vector
key_ord <- c(set1_sf$id, set2_sf$id)
ggplot() +
geom_sf(data = set1_sf, aes(colour = id), lwd = 0.8) +
geom_sf(data = set2_sf, aes(colour = id), lwd = 0.8) +
scale_colour_manual(name = "Lines",
values = c(palette, "black"),
breaks = key_ord,
labels = key_ord)