4

My question combines two separate issues posted on before on Stackoverflow: i. Adding multiple legends to ggplot and ii. Add line legend to geom_sf.

I would like to add multiple legends to ggplot2 (as in the first post), but am using sf. This complicates filling up the aesthetic space. The answer suggested in i. above does not work well with multiple types of geometries -- we cannot assign points and lines to a single class and then use factors. In my case, I have several line and point shapefiles, and simply want to add a separate legend entry for each shapefile added.

There seems to be no need to invoke aes(), but aes() may be the only way to call a legend.

Reproducible example

I would like to do something similar to the following (borrowing from (i)), but without the as.factor so that I could have separate calls of geom_sf:

library(sf)
library(ggplot2)

# reproducible data
lon<-c(5.121420, 6.566502, 4.895168, 7.626135)
lat<-c(52.09074, 53.21938, 52.37022, 51.96066)
cities<-c('utrecht','groningen','amsterdam','munster')
size<-c(300,500,1000,50)

xy.cities<-data.frame(lon,lat,cities,size)

# line example
line1 <- st_linestring(as.matrix(xy.cities[1:2,1:2]))
line2 <- st_linestring(as.matrix(xy.cities[3:4,1:2]))

lines.sfc <- st_sfc(list(line1,line2))
simple.lines.sf <- st_sf(id=1:2,size=c(10,50),geometry=lines.sfc)

ggplot() + 
 geom_sf(data= simple.lines.sf, aes(colour = as.factor(id)), show.legend = "line")

That is, something more like:

ggplot() + 
 geom_sf(data= dataset1, color="red" ) +
 geom_sf(data= dataset2, color="blue" )

1 Answer 1

4

I'm not certain that I understand exactly what you want. Here we map values "A" and "B" to the color aestetic in order to obtain a legend and then we customize the colors with scale_color_manual

dataset1 <- st_sf(st_sfc(list(line1)))
dataset2 <- st_sf(st_sfc(list(line2)))

ggplot() + 
    geom_sf(data= dataset1, aes(color="A"), show.legend = "line") +
    geom_sf(data= dataset2, aes(color="B"), show.legend = "line") +
    scale_color_manual(values = c("A" = "red", "B" = "blue"), 
                       labels = c("Line1", "Line2"),
                       name = "Which line ?") 

enter image description here

5
  • Thanks! That is precisely what I wanted -- to be able to force an aesthetic and then call it later. I didn't realized you could force a constant like that: "A" and "B".
    – C Sev
    Commented Feb 14, 2018 at 23:29
  • If anyone else comes across this with a similar issues and is then trying to figure out how to combine legends, here are some useful links: Combine legends for color and shape into a single legend
    – C Sev
    Commented Feb 14, 2018 at 23:32
  • Although, now I get the following error: Error: length(rows) == 1 is not TRUE which seems to be coming from invoking show.legend = "line" -- if I exclude show.legend there's no problem, except that the legend figure is a fill not a line.
    – C Sev
    Commented Feb 14, 2018 at 23:55
  • I don't have any error message with the provided code, ggplot2_2.2.1.9000 and sf_0.5-4... Commented Feb 14, 2018 at 23:59
  • Ok -- after restart I didn't either. Thanks!
    – C Sev
    Commented Feb 15, 2018 at 14:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.