Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ggmap does not work with plot_sf/geom_sf #336

Closed
yeedle opened this issue May 11, 2017 · 7 comments
Closed

ggmap does not work with plot_sf/geom_sf #336

yeedle opened this issue May 11, 2017 · 7 comments

Comments

@yeedle
Copy link

yeedle commented May 11, 2017

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)

@edzer
Copy link
Member

edzer commented May 11, 2017

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.

@yeedle
Copy link
Author

yeedle commented May 11, 2017

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

@yeedle
Copy link
Author

yeedle commented May 11, 2017

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.

@edzer edzer closed this as completed May 11, 2017
@mikoontz
Copy link

mikoontz commented Oct 25, 2017

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() tidyverse/ggplot2#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.

@enjoyjubilee
Copy link

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

@edzer
Copy link
Member

edzer commented Feb 20, 2019

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.

@aourednik
Copy link

@edzer The need for API key for ggmap::get_map() seems to be unrelated to this issue. I have the same issue with ggmap::getstamenmap() that requires no key.

But, good news, the workaround of @mikoontz still works ! Just add inherit.aes = FALSE in the argument of geom_sf().
On the ggmap side, @dkahle, would you have time to fix this? Making the workaround dispensible would offer smooth integration between the two great packages sf and ggmap :-) It takes users time to find this workaround and some give up...

Also, why not remove the obligation to name the bounding box vector in ggmap::getmap() and ggmap::getstamenmap()?
ggmap requires ´c("left", "bottom", "right", "top")´, while st_bbox() names its vector c("xmin" , "ymin", "xmax", "ymax"). This uselesly generates an incomptability that can only be circumvened by another workaround: st_bbox(mespoints) %>% setNames(c("left", "bottom", "right", "top")) %>% get_stamenmap(...)

Here a working example :

mespoints <- st_read('{ "type": "FeatureCollection", "features": [
    { "type": "Feature", "geometry": {
        "coordinates": [9.007992484256647,46.0299246522398],
        "type": "Point"
    }},
    { "type": "Feature", "geometry": {
        "coordinates": [8.9478934338552,45.977147786636834],
        "type": "Point"
    }},
    {"type": "Feature", "geometry": {
        "coordinates": [8.8329890317913,46.04030106008443],
        "type": "Point"
    }},
    {"type": "Feature", "geometry": {
        "coordinates": [8.950073186262301,45.913272474209464],
        "type": "Point"
    }}
]}')

library(ggmap)
fondsCarte <- st_bbox(mespoints) %>% setNames(c("left", "bottom", "right", "top")) %>% get_stamenmap(maptype = "terrain",zoom=13)
ggmap(fondsCarte) + geom_sf(data=mespoints, inherit.aes = FALSE)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants