6 Producing maps for plotting

6.1 Producing maps using ggmap

The R package ggmap can download maps from Google maps (or OpenStreetMap) which can then be used as a background layer in a ggplot2 plot.

The function get_map(location, zoom) downloads a map. location can be a pair of longitude and latitude, a character string describing the location, or a bounding box. zoom controls the zoom level (from 3 (continent) to 21 (highest resolution)). The optional argument maptype can be used to select the type of map downloaded (for example "roadmap", "hybrid" or "satellite" when using Google maps)

Note that access to the Google API (for Google map tiles and for geolocation (translation of location description to GPS coordinates) requires a Google API key. When using a bounding box and "stamen" as source, no API key is required.

library(ggmap)
boundingbox <- c(left = 5.855, bottom = 51.817, right = 5.871, top = 51.826)
map <- get_map(boundingbox, zoom=16, source="stamen")

The map can the be plotted using ggmap(map). Layers can be added to the map using the usual ggplot2 commands.

ggmap(map) + 
    geom_label(x=5.862, y=51.823, label="Radboud University") 

6.1.1 Task

In this task, we will use data from two tibbles, stations and trips. These contain information on the list of bike stations of the Bay Area Bike Share system in the San Francisco Bay Area.

It has the following columns.

Column name Description
station_id Numeric identifier of the station
name Name of the station
lat Latitude of the station
long Longitude of the station
dockcount Number of docks at the station
city City in which the station is located

The tibble trips contains all trips made during August 2015. It has the following columns.

Column name Description
trip_id Numeric identifier of the trip
trip_duration Duration of the trip in seconds
day Day of the month the trip was started
hour Decimal hour when the strip was started
start_station_id Numeric identifier of the station where the trip started
end_station_id Numeric identifier of the station where the trip ended
bike_id Numeric identifier of the bike used
end_date Date and time the trip ended
subscriber_type User type (“Subscriber” or “Customer”)
  1. Plot the locations of each of the bike stations. You can use the following bounding box below for your map
boundingbox <- c(left = -122.5, bottom = 37.25, right = -121.75, top = 38)
  1. (Harder) For trips within the city of San Francisco, use the code below to create an origin-destination matrix. The \((i,j)\)th entry contains the number of trips from station \(i\) to station \(j\).

Create a plot representing the number of trips between the stations. Use the line thickness or transparency to indicate the number of trips. You can use the following bounding box below for your map

library(tidyverse)
load(url("https://github.com/UofGAnalyticsData/R/raw/main/Week%206/t3.RData"))
sf_stations <- stations %>%
    filter(city=="San Francisco") 

od <- trips %>%
         filter(start_station_id%in%sf_stations$station_id,
                end_station_id%in%sf_stations$station_id) %>%
         group_by(start_station_id, end_station_id) %>%
         summarise(ntrips=n()) 
## `summarise()` has grouped output by 'start_station_id'. You can override using
## the `.groups` argument.
odm <- od %>%
         spread(end_station_id, ntrips, fill=0) 

odm <- as.matrix(od[,-1])
rownames(odm) <- od$start_station_id

od2 <- od %>% 
    full_join(od, by=c("start_station_id"="end_station_id", "end_station_id"=
"start_station_id")) %>%
    replace_na(list(ntrips.x=0, ntrips.y=0)) %>%
    mutate(ntrips=ntrips.x+ntrips.y) %>%
    select(-ntrips.x, -ntrips.y) %>%
    filter(start_station_id<end_station_id)

odall <- 
    od2 %>% 
    inner_join(sf_stations, by=c("start_station_id"="station_id")) %>%
    inner_join(sf_stations, by=c("end_station_id"="station_id"), suffix=c("","_end"))


boundingbox <- c(left = -122.43, bottom = 37.76, right = -122.38, top = 37.81)

6.1.2 Answer

For part (a) we can use the following code.

load(url("https://github.com/UofGAnalyticsData/R/raw/main/Week%206/t3.RData"))
boundingbox <- c(left = -122.5, bottom = 37.25, right = -121.75, top = 38)

map <- get_map(boundingbox, zoom=9, source="stamen")

ggmap(map) + 
    geom_point(data=stations, aes(x=long, y=lat,  colour=city)) +
    xlab("Longitude") + ylab("Latitude") + 
    ggtitle("Bicycle stations in the San Francisco Bay Area")

For part (b) we can use the following code.

library(magrittr)
boundingbox <- c(left = -122.43, bottom = 37.76, right = -122.38, top = 37.81)
map <- get_map(boundingbox, zoom=13, source="stamen")



ggmap(map) + 
    geom_point(data=sf_stations, aes(long, lat, size=dockcount), col="orange") +
    geom_segment(data=odall, aes(long, lat, xend=long_end, yend=lat_end, alpha=ntrips), col="orange")+
    xlab("Longitude") + ylab("Latitude") + 
    ggtitle("Bicycle trips in San Francisco")

6.1.3 Producing maps using leaflet

Maps plotted using ggmap cannot be panned and zoomed in and out like maps on Google Maps or OpenStreetMap. The package leaflet allows for this. It works somewhat the other way round than ggmap: rather than downloading the map and integrating it into an R plot it overlays the data over the map interface.

The following command puts a marker where Radboud University is located.

library(leaflet)
leaflet() %>%
   addTiles(urlTemplate = "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png") %>% 
   addMarkers(lng=5.862, lat=51.823, popup="Radboud University")

The argument urlTemplate is only required when opening the file locally.

Leaflet map showing Radboud University

Lines can be added to the map using the function addPolylines.

The data frame subway contains the GPS coordinates of all subway stations in Glasgow. You can produce a map of the Glasgow subway network using the following code.

subway2 <- rbind(subway, subway[1,])     # Make sure line goes back to Hillhead
leaflet() %>%   
   addTiles(urlTemplate = "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png") %>% 
   addMarkers(lng=-4.2885, lat=55.8715, popup="The University of Glasgow") %>%
   addPolylines(subway2$long, subway2$lat, color="#ff6200", opacity=0.5, weight=10) %>% 
   addCircleMarkers(subway$long, subway$lat, popup=subway$station, color="#ff6200", 
                    opacity=1, fillColor="#4d4f53", fillOpacity=1) 

Leaflet map showing the Glasgow Subway