Add a circle to ggmap
Asked Answered
M

2

11

Let's assume I generate a map of London using ggmap package:

library(ggmap)
library(mapproj)

map <- get_map(location = "London", zoom = 11, maptype = "satellite")

p <- ggmap(map)+ 
     theme(legend.position = "none") 

print(p)

Now I would like to add to this plot a circle with some center coordinates(let's say: lon=-0.1, lat=52.23) and radius expressed e.g. in kilometers. I tried to use a solution from similar question(Draw a circle with ggplot2), where you can just add to the function a statement like this:

p <- p + annotate("path",
                  x = xc+r*cos(seq(0,2*pi,length.out=100)),
                  y = yc+r*sin(seq(0,2*pi,length.out=100)))

It works but the circle is not really a circle due to the different scale. Is it possible to draw it correctly? Any help would be appreciated!

EDIT: I found solution (https://gis.stackexchange.com/questions/119736/ggmap-create-circle-symbol-where-radius-represents-distance-miles-or-km) that uses different package and the output is correct. Nevertheless, if anyone knows how to do it using ggmap please share it.

Monte answered 21/5, 2015 at 7:53 Comment(4)
Have you tried adding + coord_equal() to the end of your map plot?Ulani
Yes, but I think that then it is not reliable in terms of distanceOxheart
Plus the output is different e.g from the output obtained in this website: freemaptools.com/radius-around-point.htmOxheart
the biggest problem I see with your code for creating the circle is that your center is in lat,long pairs and not distance pairs in a given mile or km pair... if you use this post link you can generate a set of lat long pairs that should generate a circle at the given size regardless of zoomElum
P
1

Here is a solution using the sf package and ggplot::geom_sf. First, create a point from coordinates and transform to London's UTM zone (30u) with EPSG 32630 so that distance can be determined:

# dev version of ggplot2 required
library(sf)
library(ggplot2)

sf_pt <- st_point(c(-0.1, 52.23)) %>% 
  st_sfc(crs = 4326) %>%
  st_transform(32630)

then add a buffer

sf_pt %<>% st_buffer(100)

now transform back to epsg:4326 (lat/lon WGS84) and plot with ggmap

p <- ggmap(map) +
  geom_sf(data = sf_pt %>% st_transform(4326)) +
  theme(legend.position = "none") 

print(p)
Protoxylem answered 27/2, 2018 at 10:42 Comment(0)
C
0

You can get the longitude and latitude span from the map object:

> m = get_map(location="london", zoom=11, maptype="satellite")
> corners = attributes(m)$bb
> delta.x = corners["ur.lon"] - corners["ll.lon"]
> delta.y = corners["ur.lat"] - corners["ll.lat"]

Then adjust your path accordingly. Notice also that the ggmap package has a function called LonLat2XY (see reference).

Convene answered 25/5, 2015 at 16:13 Comment(2)
Care to demonstrate what "accordingly" means in this case?Hetti
Doesn't 'accordingly' just involve linking the circle size parameter to the variable that is getting dropped in? So for example, if your location lat and lon are 37.8 and 122.4 respectively, your corners for the delta.y might be 37.9[ur] - 37.7[ll] - but you will have to build the calculation on to your references to get the circles the size you want them for every coordinate you feed it.Mudlark

© 2022 - 2024 — McMap. All rights reserved.