After an interesting talk at the August EdinbR meeting, I wanted to try a bit of RMarkdown to document the process of making maps in Leaflet for R. Using data from the UK Lakes Portal, I ended up making a nice slippy map showing the varying depths of lochs in Assynt:
To add labels to the lochs showing their name and mean depth, we can set up a list with a combination of HTML and our variable names and pass it to htmltools::HTML with lapply:
labels <- sprintf(
"<strong>%s</strong><br/>Mean depth: %gm",
lakes_l$NAME, lakes_l$MNDP
) %>% lapply(htmltools::HTML)
The leaflet library is quite inuitive, so it will automatically centre the map and set the zoom level based on (presumably) the bounds of your data. In this case, I wanted to zoom in one level further even though a small amount of data would be outside the map’s view. To do this, you can pass a zoom level to Leaflet’s setView function, but it requires a latitude and longitude for the map’s centre rather than being able to use the centre point it automatically set. I couldn’t find a way to get the centre point of a spatial data frame, but we can get the bounding box using sf’s st_bbox and compute the centre thusly:
latitude <- as.numeric((st_bbox(lakes_l)["ymin"]+st_bbox(lakes_l)["ymax"])/2)
longitude <- as.numeric((st_bbox(lakes_l)["xmin"]+st_bbox(lakes_l)["xmax"])/2)
To categoprise the data, we first need to set up some bins for the data and define a suitable colour scheme. We’re using data from Mean Depth (MNDP) here:
bins <- c(0, 2, 4, 6, 8, 10, 15, 20, Inf)
pal <- colorBin("Blues", domain = lakes_l$MNDP, bins = bins)
Then we can create our leaflet map using the following code, styling the data based on this tutorial on chloropleth maps:
map1 <- leaflet(lakes_l, width = "100%") %>%
setView(lat=latitude, lng=longitude, zoom=11) %>%
addProviderTiles(providers$Stamen.TonerLite) %>%
addPolygons(fillColor = ~pal(MNDP),
weight = 0.2,
opacity = 1,
color = "black",
fillOpacity = 1,
highlight = highlightOptions(
weight = 1,
color = "black",
fillOpacity = 0.7,
bringToFront = TRUE),
label = labels,
labelOptions = labelOptions(
style = list("font-weight" = "normal", padding = "3px 8px"),
textsize = "15px",
direction = "auto")
) %>%
addLegend(pal = pal, values = ~MNDP, opacity = 0.7, title = "Mean depth (m)", position = "bottomright")
Once we’ve set up one map, it’s really easy to use the same data and present a different variable. Here’s a map of Shoreline Development Index (SDI, showing how complex the loch’s shape is) with a different zoom level:
When writing this documentation, I wanted to show the output from chunks of code then later show the code itself, ideally without repeating the code in the script. This can be done by first naming a code chunk, then referncing it by name later on with different parameters. Here I am showing the code from the chunk named ‘leaf’ without re-running it:
```{r echo=TRUE, eval=FALSE}
<<leaf>>
```