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)
The warning could have been a hint:
plot(st_transform(nc, 3857)[1], col = 0, bgMap = nc_map)

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.
Most helpful comment
For posterity, I'm finding some success when I get the
#> Error in FUN(X[[i]], ...): object 'lon' not founderror to use theinherit.aes = FALSEargument in thegeom_sf()function call:Oddly, I sometimes get a
Error in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : polygon edge not foundwhen 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 withingeom_sf()https://github.com/tidyverse/ggplot2/issues/2252)I think the original error may be related to the
lonandlatcolumns created in thefourCornersdata.frame within theggmap()function as the ggplotpis being created. That is, when you get a basemap withget_map()and try to ggplot it withggmap(), theggmap()function returns a ggplotpthat uses anaes(x = lon, y = lat)aesthetic. Thesfobjects that you add on top using thegeom_sf()function tries to inherit the x and y mapping from that original layer, but it really needs to use the $geometry column.