2

I have a number of maps that I'm generating in R using the sf library and I would like to have a nice looking legend. Unfortunately, it seems that the standard legend for geom_sf() are these ugly looking boxes. The only SO post I could find on adjusting shapes in ggplot2 legends is here.

The here is to use guides(colour = guide_legend(override.aes = list(shape = 16))); however, this only seems to work for geom_point() and not for geom_sf().

Unless someone can suggest an alternative method for changing the shape of legend objects I will need to design a custom legend in Inkscape and align this along with various maps.

Here's a snippet of the code to show what I've tried already:

legend <- image_read_svg('https://svgshare.com/i/FDV.svg')
p1 <- ggplot() + 
  geom_sf(data=otherroads, size = .45, aes(color=SUFTYPABRV)) + 
  geom_sf(data=allroads, size = .55, aes(color=SUFTYPABRV)) + 
  scale_color_manual(values = plotcolors, guide = "legend") + theme_map() +
  labs(title = "Sydney")

ggdraw() +
 draw_plot(p1) +
 draw_image(legend, width = 0.4, hjust = -0.75, vjust = 0.43)

Good legend location example

The output looks good in this case; however, this won't work for me because it requires manual tweaking for every plot.

What I would like is for the location of this legend to be dynamically placed according to the ggplot object, which depends upon the city I'm plotting.

Bad legend location example

The code (and data) in it's entirety can be cloned from github: https://github.com/moldach/map-help.git

1 Answers1

2

This answer is not to adress the legend placement, but changing the legend icons. From your examples, I gather your data produces a legend that looks like this by default:

# example from the geom_sf help page
nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)

# throwing in some random categorical data
nc$catvar <- sample(LETTERS[1:5], nrow(nc), replace = TRUE)

ggplot(nc) +
  geom_sf(aes(colour = catvar))

enter image description here

Not too long ago, ggplot added the ability to set what legend shape you wanted by implicitly (via the ellipsis) adding the key_glyph argument to all layers, such as geoms and stats.

ggplot(nc) +
  geom_sf(aes(colour = catvar), key_glyph = "timeseries")

enter image description here

You could use this, to set the glyph to points and then use the override.aes trick to get the shapes that you want.

ggplot(nc) +
  geom_sf(aes(colour = catvar), key_glyph = "point") +
  guides(colour = guide_legend(override.aes = list(size = 3, shape = c(15:19))))

enter image description here

It should work with all the regular legend placement tools that are already in ggplot. You might have to specify locations specific for the plot, but at least you won't have to export your legend to svg files first before adding them.

teunbrand
  • 33,645
  • 4
  • 37
  • 63