I am dealing with multiple sf geometries in ggplot and would like to display legend in the form of a point, a line, and a square (for the polygon). However, geom_sf legend combines my geometry features (i.e. combining line and point) displayed below:
library(ggplot2)
library(sf)
poly1 <- cbind(lon = c(5, 6, 7, 5), lat = c(52, 53, 51, 52))
poly <- st_sf(st_sfc(st_polygon(list(poly1))))
line <- st_sf(st_sfc(list(st_linestring(cbind(lon = c(5.5, 4.5), lat = c(53.5, 54.5))))))
point <- st_sf(st_sfc(st_point(cbind(lon = 5.5, lat = 52.7))))
ggplot() +
geom_sf(data = poly, aes(fill = "A")) +
geom_sf(data = point, aes(colour = "B"), show.legend = "point") +
geom_sf(data = line, aes(colour = "C"), show.legend = "line") +
scale_fill_manual(values = c("A" = "yellow")) +
scale_colour_manual(values = c("B" = "pink", "C" = "purple")) +
theme_minimal()
I would like three separate legends, a single yellow square, a pink point, and a purple line on the same image illustrated below. It is only the case when I plot individual geometry but not the combination of three.
I looked up similar topics, but none of them dealt with point geometries i.e. https://github.com/tidyverse/ggplot2/issues/2460
Would anyone offer any insight on this?
GitHub issue: https://github.com/tidyverse/ggplot2/issues/2763
Inspired by the comment from @Axeman, this issue and this post, the problem is solved using the override.aes
argument in guide_legend()
:
library(ggplot2)
library(sf)
poly1 <- cbind(lon = c(5, 6, 7, 5), lat = c(52, 53, 51, 52))
poly <- st_sf(st_sfc(st_polygon(list(poly1))))
line <- st_sf(st_sfc(list(st_linestring(cbind(lon = c(5.5, 4.5), lat = c(53.5, 54.5))))))
point <- st_sf(st_sfc(st_point(cbind(lon = 5.5, lat = 52.7))))
ggplot() +
geom_sf(data = poly, aes(fill = "A")) +
geom_sf(data = point, aes(colour = "B"), show.legend = "point") +
geom_sf(data = line, aes(colour = "C"), show.legend = "line") +
scale_fill_manual(values = c("A" = "yellow"), name = NULL,
guide = guide_legend(override.aes = list(linetype = "blank", shape = NA))) +
scale_colour_manual(values = c("B" = "pink", "C" = "purple"), name = NULL,
guide = guide_legend(override.aes = list(linetype = c("blank", "solid"),
shape = c(16, NA)))) +
theme_minimal()
I know how to seperate the legends, they only get combined now because you are mapping color twice. By mapping shape to the points and setting the color, you can get around that:
ggplot() +
geom_sf(data = poly, aes(fill = "A")) +
geom_sf(data = point, aes(colour = "B"), show.legend = "point") +
geom_sf(data = line, aes(shape = "C"), show.legend = "line", color = 'purple') +
scale_fill_manual(name = NULL, values = c("A" = "yellow")) +
scale_colour_manual(name = NULL, values = c("B" = "pink")) +
scale_shape_discrete(
name = NULL,
guide = guide_legend(override.aes = list(color = 'purple'))) +
theme_minimal()
But: the point and line are still showing up in all three legends. I don't think they should! Perhaps you can fill a github issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With