We all have been there when we wanted to plot a geographical data in R. But somehow couldn’t have done it the way we wanted. Either it’s because of the long procedure we have to go through to enable Google maps api or just wasn’t satisfied the graphics. But, what if I tell you there exists a package which can help you plot geographical data with just a few lines of code without signing in anywhere! Using Leaflet we can plot beautiful maps in R. Before, we jump to the actual code, let’s see what Leaflet actually is,
Leaflet is one of the most popular open-source libraries for interactive maps. It is written in JavaScript. Following are some of the features of the Leaflet:
Following tutorial assumes that you have R and RStudio installed on your computer.
#install.packages("leaflet")
# to install the development package from github, run
# devtools::install_github("rstudio/leaflet")
There are three steps that are required to create an interactive web map in R using leaflet: 1. loading the leaflet library 2. initializing the leaflet widget using the leaflet() function 3. adding a map tile
Similar to the packages in the tidyverse, the leaflet package makes use of the pipe operator (i.e., %>%) from the magrittr package to chain function calls together. This means we can pipe the result of one function into another without having to store the intermediate output in an object.
To create a web map in R, you will chain together a series of function calls using the %>% operator. Our first function leaflet() will initialize the htmlwidget then we will add a map tile using the addTiles() function.
library(leaflet)
## Warning: package 'leaflet' was built under R version 4.0.5
leaflet() %>%
addTiles()
And that’s it! Simple, isn’t it? We just 2 lines of code, and we already have an interactive map. I know it doesn’t do anything than just zooming in and out so, let’s make it more interactive.
In the code above, addTiles() is used to add the default OpenStreetMap(OSM) tile to the leaflet map. Map tiles weave multiple map images together. The map tiles presented adjust when a user zooms or pans the map enabling the interactive features.
The leaflet package comes with more than 100 map tiles that you can use. These tiles are stored in a list called providers and can be added to your map using addProviderTiles() instead of addTiles().
To see the available provider tiles, we need to run the following code:
names(providers)[1:5]
## [1] "OpenStreetMap" "OpenStreetMap.Mapnik" "OpenStreetMap.DE"
## [4] "OpenStreetMap.CH" "OpenStreetMap.France"
Now, that we have got the different providers, let’s try one of them and see how it’s different than the default one.
To add a custom provider tile to our map we will use the addProviderTiles() function. The first argument to addProviderTiles() is your leaflet map, which allows us to pipe leaflet() output directly into addProviderTiles(). The second argument is provider, which accepts any of the map tiles included in the providers list.
leaflet() %>%
addProviderTiles(provider = "CartoDB.DarkMatterNoLabels")
I’ve used the ‘CartoDB.DarkMatterNoLabels’ provider. And it has turned the map into dark mode actually!
You may have noticed that, by default, maps are zoomed out to the farthest level. Rather than manually zooming and panning, we can load the map centered on a particular point using the setView() function.
The default zoom level is 0 and can reach upto 19. 0 being the zoomed out stage.
leaflet() %>%
addProviderTiles("CartoDB") %>%
setView(lat = 27.1751, lng = 78.0421, zoom = 16)
We can limit users’ ability to pan away from the map’s focus using the options argument in the leaflet() function. By setting minZoom anddragging, we can create an interactive web map that will always be focused on a specific area. Although, user can zoom out using controls.
leaflet(options =
leafletOptions(minZoom = 14, dragging = FALSE)) %>%
addProviderTiles("CartoDB") %>%
setView(lng = 78.0421, lat = 27.1751, zoom = 16)
Alternatively, if we want our users to be able to drag the map while ensuring that they do not stray too far, we can set the maps maximum boundaries by specifying two diagonal corners of a rectangle.
library(tibble)
## Warning: package 'tibble' was built under R version 4.0.5
#R package that provides easy to use functions for creating tibbles, which is a modern rethinking of data frames.
wonders <- tibble(
place = c("Taj Mahal - India", "Petra - Jordan", "Christ the Redeemer - Brazil", "Colosseum - Italy"),
lon = c(78.0421, 35.4444, 43.2105, 12.4922),
lat = c(27.1751, 30.3285, 22.9519, 41.8902))
leaflet(options = leafletOptions(
# Set minZoom and dragging
minZoom = 12, dragging = TRUE)) %>%
addProviderTiles("CartoDB") %>%
# Set default zoom level
setView(lng = wonders$lon[2], lat = wonders$lat[2], zoom = 10) %>%
# Set max bounds of map
setMaxBounds(lng1 = wonders$lon[2] + .05,
lat1 = wonders$lat[2] + .05,
lng2 = wonders$lon[2] - .05,
lat2 = wonders$lat[2] - .05)
Try, dragging this map. What do you notice. It cannot be dragged more than the max bounds we have set i.e. 0.05. So, the map stays in the focused mode and cannot be dragged further than set limits.
So far we have been creating maps with a single layer: a base map. We can add layers to this base map similar to how you add layers to a plot in ggplot2. One of the most common layers to add to a leaflet map is location markers, which you can add by piping the result of addTiles() or addProviderTiles() into the add markers function.
For example, if we plot Taj Mahal by passing the coordinates to addMarkers() as numeric vectors with one element, our web map will place a blue drop pin at the coordinate.
leaflet() %>%
addProviderTiles("OpenStreetMap") %>%
addMarkers(lng = wonders$lon[2], lat = wonders$lat[2])
To make our map more informative we can add popups. To add popups that appear when a marker is clicked we need to specify the popup argument in the addMarkers() function. Once we have a map we would like to preserve, we can store it in an object. Then we can pipe this object into functions to add or edit the map’s layers.
wondersMap <- leaflet() %>%
addTiles() %>%
addMarkers(lng = wonders$lon, lat = wonders$lat,
popup = wonders$place)
## We can add layers to the existing leaflet R object
map_zoom <- wondersMap %>%
setView(lng = wonders$lon[4], lat = wonders$lat[4], zoom = 2)
map_zoom
If you are storing leaflet maps in objects, there will come a time when you need to remove markers or reset the view. You can accomplish these tasks with the following functions.
To remove the markers and to reset the bounds of our m map we would:
map_zoom <- map_zoom %>%
addMarkers(lng = wonders$lon, lat = wonders$lat) %>%
setView(lng = 20.6843, lat = 88.5678, zoom = 5)
map_zoom %>%
clearMarkers() %>%
clearBounds()