Most of the content in this document is blatently copied from here and here. Visit these sites for more detail on using Leaflet with R.
Leaflet is one of the most popular open-source JavaScript libraries for interactive maps. It’s used by websites ranging from The New York Times and The Washington Post to GitHub and Flickr, as well as GIS specialists like OpenStreetMap, Mapbox, and CartoDB.
This R package makes it easy to integrate and control Leaflet maps in R.
sp
or sf
packages, or data frames with latitude/lon gitude columnsTo install this R pacakge, run this command at your R prompt:
install.packages("leaflet",repos = "http://cran.us.r-project.org")
# to install the development version from Github, run
# devtools::install_github("rstudio/leaflet")
Once installed, you can use this package at the R console, within R Markdown documents, and within Shiny applications.
You create a Leaflet map with these basic steps:
leaflet()
.addTiles
, addMarkers
, addPolygons
) to modify the map widget.Here’s a basic example:
library(leaflet)
m <- leaflet() %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addMarkers(lng=-122.316, lat=47.653, popup="Your Current Location")
m # Print the map
The function leaflet()
returns a Leaflet map widget, which stores a list of objects that can be modified or updated later.
The map widget can be initialized with certain parameters. This is achieved by populating the options argument as shown below.
#Set value for the minZoom and maxZoom settings.
leaflet(options = leafletOptions(minZoom = 0, maxZoom = 18))
The leafletOptions()
can be passed any option described in the leaflet reference document. Using the leafletOptions()
, you can modify elements such as the map projection, map boundaries, interaction options and more!
You can manipulate the attributes of the map widget using a series of methods. Please see the help page ?setView
for details.
setView()
sets the center of the map view and the zoom level;fitBounds()
fits the view into the rectangle [lng1, lat1] – [lng2, lat2];clearBounds()
clears the bound, so that the view will be automatically determined by the range of latitude/longitude data in the map layers if provided;Leaflet supports basemaps using map tiles, popularized by Google Maps and now used by nearly all interactive web maps. The easiest way to add tiles is by calling addTiles()
with no arguments; by default, OpenStreetMap tiles are used. Alternatively, many popular free third-party basemaps can be added using the addProviderTiles()
function, which is implemented using the leaflet-providers plugin. In the example below, we use the Esri.WorldImagery
basemap. You can often overlay basemaps if you want additional information - take a moment to explore the options on the leaflet-providers plugin.
leaflet() %>% setView(lng=-122.316, lat=47.653, zoom = 14) %>%
addProviderTiles(providers$Esri.WorldImagery) %>%
addMarkers(lng=-122.316, lat=47.653, popup="Your Current Location")
Both leaflet()
and the map layer functions have an optional data parameter that is designed to receive spatial data in one of several forms:
sp
package:
maps
package:
The data
argument is used to derive spatial data for functions that need it; for example, if data is a SpatialPolygonsDataFrame
object, then calling addPolygon
on that map widget will know to add the polygons from that SpatialPolygonsDataFrame
. The most common calls are as follows:
addMarkers()
to add point dataaddAwesomeMarkers()
to add point data
addMarkers()
function but additionally allows you to specify custom colors for the markers as well as icons from the Font Awesome, Bootstrap Glyphicons, and Ion icons icon libraries. It is pretty fun.addCircleMarkers()
to add point data
addCircles()
to add point data
addPolygons()
to add polygon dataaddPolylines()
to add spatial line dataaddRasterImage()
to add raster data (Warning: this can be slow)It is straightforward to derive these variables from sp
or sf
objects since they always represent spatial data in the same way. On the other hand, for a normal matrix or data frame, any numeric column could potentially contain spatial data. So we resort to guessing based on column names:
lat
or latitude
(case-insensitive)lng
, long
, or longitude
You can always explicitly identify latitude/longitude columns by providing lng
and lat
arguments to the layer function.
Now we will work on the same example as before, but this time in an interactive format. Each section below will describe a bit of the final leaflet map - run the final block of code to generate the final map.
First, we need to generate our data. The honey_sf
dataframe currently consists of several years of data for each state. Although leaflet
can effectively show time series, for now we want to get an average price per lb over the time series. We use the group_by
function to get the mean price of honey for each state over all years of data.
honey_sf = read_sf("honey.shp")
honey_sf_avg = honey_sf %>%
dplyr::group_by(State) %>%
dplyr::summarize(avg_prcprlb = mean(prcprlb, na.rm=TRUE)) %>%
dplyr::ungroup()
Next, we will create a custom color palette that depends on average price per pound of honey.
pal <- colorBin("YlOrRd", domain = honey_sf_avg$avg_prcprlb, bins = 5)
Now on to plotting your map! Although the satellite imagery is nice, it’s likely a bit too much for what we need. We are now using a fairly simple basemap, the CartoDB.Positron
basemap. We are going to add polygons for each US state (colored by the average price per pound of honey), labels that pop-up when you hover over a particular state, and a legend.
The below example uses the highlightOptions
parameter to emphasize the currently moused-over polygon. The bringToFront = TRUE
argument is necessary to prevent the thicker, white border of the active polygon from being hidden behind the borders of other polygons that happen to be higher in the z-order.
leaflet() %>%
addProviderTiles(providers$CartoDB.Positron) %>% # Add a nice, neutral background
addPolygons(data = honey_sf_avg, # Add polygons
fillColor = ~pal(avg_prcprlb), # Color the polygons by the average price per lb of honey
weight = 2, # Increase polygon outline
opacity = 1, # Make the polygon outline not see-through at all
color = "white", # Make the polygon outlines white
dashArray = "3", # Make the polygon outlines dashed
fillOpacity = 0.7, # Make the polygons somewhat see-through
highlightOptions = highlightOptions( # Defines pop-up labels
weight = 5,
color = "#666",
dashArray = "",
fillOpacity = 0.7,
bringToFront = TRUE),
label = paste("<strong>State</strong>: ", # Make this part of the label bolded
honey_sf_avg$State, "<br>",
"<strong>Price Per LB</strong>: ", # Make this part of the label bolded
"$",round(honey_sf_avg$avg_prcprlb, 2)) %>%
lapply(htmltools::HTML), # We need this bit to properly apply the code creating bold words and line breaks
labelOptions = labelOptions(
style = list("font-weight" = "normal", padding = "3px 8px"),
textsize = "15px",
direction = "auto")) %>%
addLegend(data = honey_sf_avg,
pal = pal,
values = ~avg_prcprlb,
labFormat = labelFormat(prefix = "$"),
opacity = 0.7,
title = "HONEY PRICE/LB",
position = "bottomright")
There’s a ton of things not shown here you can do with leaflet! See the R
package leaflet.extras2
to add a slider that shows data through time, add current or historical weather data (see this example), and much more!
Leaflet
also includes powerful and convenient features for integrating with Shiny
applications, a a web framework for R. To learn more about Shiny, visit https://shiny.rstudio.com. Most Shiny output widgets are incorporated into an app by including an output (e.g. plotOutput
) for the widget in the UI definition, and using a render function (e.g. renderPlot
) in the server function. Leaflet maps are no different; in the UI you call leafletOutput
, and on the server side you assign a renderLeaflet
call to the output. Inside the renderLeaflet
expression, you return a Leaflet map object. Some examples are here, here, and here.
You can also publish your leaflet map directly using RPubs
. Click the blue circle in the top left-corner of your Rstudio viewer (it should say “Publish” if you hover over it) and walk through the steps to get a shareable link to your map!