I'm trying to make a map of my study site using ggmap & Stamen maps. I've seen a few similar questions but haven't figured out a way to incorporate the solution into my Stamen map code.
I have two questions regarding this: 1. How can I custom label the points on the map? 2. How can I add a scale to maps in Stamen map? (either as a line indicating distance or something like x cm on map = y km in real life)
Tcoords <- read.csv("Tcoords.csv")
My file looks like this
# trap latitude longitude
1 52.34431 0.5374620
2 52.34281 0.5382080
3 52.34468 0.5406787
4 52.34357 0.5398280
5 52.34431 0.5397050
6 52.34516 0.5406294
In response to the suggestion, I've pasted the results to dput(head(Tcoords)) here:
structure(list(trap = c("1", "2", "3", "4", "5", "6"), latitude = c(52.344312,
52.342809, 52.3446849, 52.343572, 52.34431, 52.3451601), longitude = c(0.537462,
0.538208, 0.5406787, 0.539828, 0.539705, 0.5406294)), row.names = c(NA,
6L), class = "data.frame")
This the code I'm using to plot my points
center = c(lon = 0.5406294, lat = 52.3451601)
qmap(center, zoom = 16, source = "stamen", maptype = "watercolor")+
geom_point(aes(x = longitude, y = latitude), size = 4, shape = 21,
fill = "dark green", data = Tcoords)
But somehow trap isn't being recognised as an object. It's probably something elementary but I'm not really sure what I've missed (new to R). I've saved "trap" as a text object here.
Thanks for your help!
I would like to suggest tmap as an alternative to ggmap. This is one of many others possible packages for creating maps CRAN Task View: Spatial but I found the scale bar that tmap generates pretty nice and the code simple.
The code to generate the final plot requires the following packages
# To create the map
library(tmap)
# To create the layer with the points given in Tcoords.csv
library(sf)
# To read the background map
library(tmaptools)
library(OpenStreetMap)
Then, we read the coordinates of the six points to be mapped and turn them into an sf object
# Read coordinates
Tcoords = dget("Tcoords.R")
# create an sf object for the six points in the file
coordinates = matrix(c(Tcoords$longitude, Tcoords$latitude), 6, 2)
tcoords_sfc = lapply(1:6, function(k) st_point(coordinates[k, ])) %>%
st_sfc(crs = 4326)
tcoords_sf = st_sf(trap = Tcoords$trap, geometry = tcoords_sfc)
Next, we find the limits of the six points (bounding box) and extend them by a factor 2.5. You can play with this factor to get maps with other scales.
bb_new = bb(tcoords_sf, ext = 2.5)
Finally we read the background map
map_osm = read_osm(bb_new, zoom = 15, type = "stamen-watercolor")
and draw the final map

with the following code
tmap_mode("plot")
tm_shape(map_osm, projection = 4326, unit = "m") +
tm_rgb() +
tm_shape(tcoords_sf) +
tm_symbols(col = "darkgreen", shape = 21, size = 2) +
tm_text(text = "trap", col = "white") +
tm_scale_bar(breaks = c(0, 50, 100, 150, 200), text.size = 0.6) +
tm_compass(position = c("left", "top"))
To get a dynamic map is even simpler as you do not have read first the basemap (read_osm) and then draw the map.
tmap_mode("view")
tm_shape(tcoords_sf, bbox = bb_new, unit = "m") +
tm_symbols(col = "darkgreen", shape = 21, size = 3) +
tm_text(text = "trap", col = "white") +
tm_basemap("Stamen.Watercolor") +
tm_scale_bar()
In the static plot, colors, text and breaks in the scale can be personalized. Note the parameter unit = "m" in the tm_shape in order to get the scale in meters, if not it will be in kilometers.
Hope you will find this alternative worth mentioning.
Getting the labels onto the map was just a matter of redefining the data source in the geom_text() function.
In order to get the scale to print on the map, it was a matter of following the solution in this question: Is there a way to add a scale bar (for linear distances) to ggmap?
#get base map
map.base <- get_map(location = center, zoom = 16, source = "stamen", maptype = "watercolor") # could also use zoom = "auto"
#get extent of base map
bb <- attr(map.base,"bb")
#define the location and length of scale bar
sbar <- data.frame(lon.start = c(bb$ll.lon + 0.1*(bb$ur.lon - bb$ll.lon)),
lon.end = c(bb$ll.lon + 0.25*(bb$ur.lon - bb$ll.lon)),
lat.start = c(bb$ll.lat + 0.1*(bb$ur.lat - bb$ll.lat)),
lat.end = c(bb$ll.lat + 0.1*(bb$ur.lat - bb$ll.lat)))
#Calculate distance in meters
library(geosphere)
sbar$distance = distGeo(c(sbar$lon.start,sbar$lat.start), c(sbar$lon.end,sbar$lat.end))
map.scale <- ggmap(map.base, extent="device") +
geom_point(aes(x = longitude, y = latitude), size = 4, shape = 21, fill = "dark green", data = Tcoords) +
geom_text(data=Tcoords, aes(label=trap, x = longitude, y = latitude), nudge_x = 0.0001, nudge_y = 0.0001, color="black") +
geom_segment(data = sbar, aes(x = lon.start, xend = lon.end, y = lat.start, yend = lat.end)) +
geom_text(data = sbar, aes(x = (lon.start + lon.end)/2,
y = lat.start + 0.025*(bb$ur.lat - bb$ll.lat),
label = paste(format(distance, digits = 4, nsmall = 2), 'm')),
hjust = 0.5, vjust = 0)
map.scale

May need to adjust the nudge_x & _y in the geom_text() function for proper label placement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With