03/10/2018

Interactive maps in R with leaflet source code

Interactive vs static

Interactive

  • nice supplementary materials!
  • label points without clutter!
  • websites, blogs
  • clustering
  • base layers
  • shiny apps
  • packages: leaflet

Static

  • publications
  • .pdf, word files
  • not too many points
  • not too close together (labling)
  • still really useful
  • packages: ggmap, cartography, sf

Leaflet

  • JavaScript mapping library
  • Nice R api, developed by rstudio docs
  • 23k github stars!
  • open source
  • similar to google maps
  • Leaflet is not the tiles
  • Google and ? are your friends!

Basic usage

# install.packages('leaflet') #    install package
library(leaflet)              #    load package
leaflet(height = 300) %>%     # 1. create map widget
  addTiles()                  # 2. add layers
  • note: leaflet uses the %>% not +
  • height argument just for presentation

Controlling bounds

leaflet(height = 400) %>% 
  addTiles() %>% 
  setView(151.2313, -33.9173, zoom = 16) # UNSW!

Scale Bars

leaflet(height = 400) %>% 
  addTiles() %>% 
  addScaleBar() ## EASY!

Minimaps

leaflet(height = 400) %>% 
  addTiles() %>% 
  addMiniMap(zoomLevelFixed = 4) ## EASY!

Both!

We are going to save this map as a base layer for later use

(base <- leaflet(height =350) %>% 
  addTiles() %>%
  addScaleBar() %>%
  addMiniMap(zoomLevelFixed = 4) %>% 
  setView(151.2313, -33.9173, zoom = 10))

Markers docs

base %>% 
  addMarkers(151.2313, -33.9173, label = 'UNSW!') %>% 
  addCircleMarkers(151.233, -33.9173, radius = 30,
                   opacity = 0.4, popup = 'UNSW', color = 'red')

eBird Example

My eBird data after 1 year, you can use the built in quakes dataset

library(dplyr, warn.conflicts = F)
obs <- read.csv('MyEBirdData.csv') %>% 
  group_by(Latitude, Longitude) %>% 
  summarise(total_species = n_distinct(Common.Name),
            my_label = paste(total_species, 'species seen'))

obs %>% glimpse()
## Observations: 56
## Variables: 4
## $ Latitude      <dbl> -36.50501, -36.50277, -36.23518, -34.70118, -34....
## $ Longitude     <dbl> 148.3060, 148.3075, 149.1260, 150.1689, 151.0726...
## $ total_species <int> 16, 7, 9, 2, 12, 31, 10, 17, 7, 7, 4, 17, 88, 5,...
## $ my_label      <chr> "16 species seen", "7 species seen", "9 species ...

base %>% 
  addCircleMarkers(obs$Longitude, obs$Latitude, label = obs$my_label)

Colouring markers - docs

# color function, maps values to colors
pal <- colorQuantile("RdYlBu", obs$total_species, n = 5) 
base %>% 
  addCircleMarkers(obs$Longitude, obs$Latitude,
                   color = pal(obs$total_species),
                   label = obs$my_label)

Marker radius

base %>% 
  addCircleMarkers(obs$Longitude, obs$Latitude,
                   color = pal(obs$total_species),
                   label = obs$my_label,
                   radius = obs$total_species)

Legend - docs

base %>% 
  addCircleMarkers(obs$Longitude, obs$Latitude, 
                   color = pal(obs$total_species),
                   label = obs$my_label) %>% 
  addLegend(pal = pal, values =  obs$total_species, position = "bottomleft")

Clustering

base %>% 
  addCircleMarkers(obs$Longitude, obs$Latitude,
                   label = obs$my_label,
                   clusterOptions = markerClusterOptions())

Shapes, Polygons, Geojson - docs

Movement data etc.

randwick <- readLines('https://raw.githubusercontent.com/coreytcallaghan/urban_greenspaces/master/greenspaces/aus-nsw-randwick_environment_park/aus-nsw-randwick_environment_park.geojson', warn = F)
base %>% clearBounds() %>% 
  addCircles(151.25, -33.93,  radius = 100, color = 'red') %>% 
  addRectangles(151.24, -33.93 - 0.01,151.25 + 0.01,  -33.93 + 0.01,
                fillColor = "transparent") %>% 
  addGeoJSON(randwick, color = 'teal')

GBIF basemaps

  • Look for a species using the search on https://www.gbif.org/
  • find one that youre interested in e.g. Swift Parrot https://www.gbif.org/species/2480052 <- note the id in the url
  • GBIF map api docs
gbif_map_url <- function (id) paste0(
    'https://api.gbif.org/v2/map/occurrence/density/{z}/{x}/{y}',
    '@2x.png?style=classic.poly&bin=hex&taxonKey=',
    id,
    '&srs=EPSG:3857')

base %>% 
  setView(151.25, -33.93, zoom = 7) %>% 
  addTiles(urlTemplate = gbif_map_url(2480052))

Base layers

leaflet(height=350) %>% 
  addProviderTiles(providers$Stamen.Toner) %>% 
  setView(151.2313, -33.9173, zoom = 16)

More base layers

  • cartodb layers link
  • some base layers need attribution
leaflet(height = 350) %>% 
  addTiles( "http://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png",
    attribution = paste("&copy; <a href=\"http://openstreetmap.org\">OpenStreetMap</a> contributors","&copy; <a href=\"http://cartodb.com/attributions\">CartoDB</a>")
) %>% setView(151.2313, -33.9173, zoom = 16)

Carto with GBIF

leaflet(height = 350) %>% 
  addTiles( "http://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png",
    attribution = paste("&copy; <a href=\"http://openstreetmap.org\">OpenStreetMap</a> contributors","&copy; <a href=\"http://cartodb.com/attributions\">CartoDB</a>")
) %>%
  addTiles(urlTemplate = gbif_map_url(2480052)) %>% 
  setView(151.2313, -33.9173, zoom = 8)

Questions