Sf: ggmap does not work with plot_sf/geom_sf

Created on 11 May 2017  路  6Comments  路  Source: r-spatial/sf

I'm getting an error when attempting to combine a ggmap object with an sf object in a plot

library(sf)
library(ggmap)

nc = st_read(system.file("shape/nc.shp", package="sf"))

nc_map = get_map(location = unname(st_bbox(nc)))
ggmap(nc_map)

ggplot(nc) + geom_sf()

So far so good. But when I try to combine them with geom_sf:

ggmap(nc_map) + geom_sf(data = nc)
#> Error in FUN(X[[i]], ...): object 'lon' not found

And similarly with plot_sf:

plot_sf(nc, bgMap = nc_map)
#> Warning in plot_sf(nc, bgMap = nc_map): crs of plotting object differs from
#> that of bgMap, which is assumed to be st_crs(3857)

(It should be noted that the same error occurs even when the zoom level in get_map is set so that all of North Carolina is included in the ggmap object)

Most helpful comment

For posterity, I'm finding some success when I get the #> Error in FUN(X[[i]], ...): object 'lon' not found error to use the inherit.aes = FALSE argument in the geom_sf() function call:

ggmap(nc_map) + 
geom_sf(data = nc, inherit.aes = FALSE)

Oddly, I sometimes get a Error in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : polygon edge not found when I do this, but I rerun the code and then it works. I haven't looked deeper into this... (quick edit: this is a known issue being worked on within geom_sf() https://github.com/tidyverse/ggplot2/issues/2252)

I think the original error may be related to the lon and lat columns created in the fourCorners data.frame within the ggmap() function as the ggplot p is being created. That is, when you get a basemap with get_map() and try to ggplot it with ggmap(), the ggmap() function returns a ggplot p that uses an aes(x = lon, y = lat) aesthetic. The sf objects that you add on top using the geom_sf() function tries to inherit the x and y mapping from that original layer, but it really needs to use the $geometry column.

All 6 comments

The warning could have been a hint:

plot(st_transform(nc, 3857)[1], col = 0, bgMap = nc_map)

x

As you see, the background map is pretty much off; ggmap gave you a warning that it is not so good at retrieving a google map from a bounding box.

The issue of ggmap not working with geom_sf has nothing to do with sf, as far as I can see.

So the issue is that sf object has to be converted with st_transform first before it can be combined with ggmap?

Oh, I see now. I'm sorry for misreading. I think this issue can be closed, I'll try to take it up with ggplot/ggmap.

For posterity, I'm finding some success when I get the #> Error in FUN(X[[i]], ...): object 'lon' not found error to use the inherit.aes = FALSE argument in the geom_sf() function call:

ggmap(nc_map) + 
geom_sf(data = nc, inherit.aes = FALSE)

Oddly, I sometimes get a Error in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : polygon edge not found when I do this, but I rerun the code and then it works. I haven't looked deeper into this... (quick edit: this is a known issue being worked on within geom_sf() https://github.com/tidyverse/ggplot2/issues/2252)

I think the original error may be related to the lon and lat columns created in the fourCorners data.frame within the ggmap() function as the ggplot p is being created. That is, when you get a basemap with get_map() and try to ggplot it with ggmap(), the ggmap() function returns a ggplot p that uses an aes(x = lon, y = lat) aesthetic. The sf objects that you add on top using the geom_sf() function tries to inherit the x and y mapping from that original layer, but it really needs to use the $geometry column.

Oh, I see now. I'm sorry for misreading. I think this issue can be closed, I'll try to take it up with ggplot/ggmap.

Hi yeedle,

I have the same issue as you did and I've read the conversation between you and edzer. However, I didn't get the meaning of " take it up with ggplot/ggmap". Could you please show the codes you ran when you solved the problem? Thanks!

Student in anxious process of a capstones project

https://github.com/dkahle/ggmap - note that ggmap now requires an API key to use the google API. An alternative would be not using google; I've seen good results from people using package ggspatial. Let us know what you end up doing.

Was this page helpful?
0 / 5 - 0 ratings