简体   繁体   中英

Format multiple geom_sf legends

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 (ie 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 ie 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM