In this blog post I’ll show how you can use R to map and analyze spatial data on wildfires in the US and in Colorado, using packages like {sf} and {leaflet}. As I write this, there are several major wildfires burning nearby along the Colorado Front Range (luckily they all seem to be under control now).
This post is about how to work with spatial data in R, and not an up-to-date or official source of verified information about the fires. See also the following caveats from the data set:
This data set is an ongoing project and as such, may be incomplete.
Currently only certified perimeters and new perimeters captured starting in 2021 are included.
After downloading the data and unzipping the file, the data can be read into R with the st_read() function from the {sf} package (Pebesma and Bivand 2023). The output gives some information about the spatial data including the coordinate reference system and bounding box.
The data we read with st_read() is actually a sf and data.frame object, which we can see if we look at its class. sf stands for Simple Features, a standard for storing spatial features like points, lines, and polygons. The spatial features are stored in a column of the data frame named geometry.
Since it is a data frame we can filter the data using standard methods like {dplyr}. I filtered the data to fires in Colorado using the attr_POOOSt column (I assume that the POOSt stands for Point of Origin State). I also limited the data to fires greater than 200 acres in size.
If we want to see the top 20 fires by size (acres), we can filter and arrange the data frame using {dplyr}. The 9th fire on the list is the Alexander Mountain Fire, one of the several fires currently burning.
Note that the largest fires are not always the most destructive; an obvious example is the Marshall Fire which is 14th on this list but was extremely destructive.
Note
The st_drop_geometry() function from {sf} allows you to drop the geometry column from a sf/data.frame object so you can work with a simple data frame that is smaller in size.
Code
co_fires|>sf::st_drop_geometry()|>slice_max(order_by =poly_Acres, n =20)|>ggplot(aes(poly_Acres, y =reorder(poly_Incid, poly_Acres)))+geom_col(fill ="red", color ="red", width =0.8)+labs(x ="Size [Acres]", y =NULL, title ="20 Largest Wildfires in Colorado", caption ="Data source: WFIGS Interagency Fire Perimeters")+scale_x_continuous(labels =scales::comma)+# add commas to axes labelstheme_minimal()
Plotting a map of Colorado fires
The data can easily be visualized on an interactive map using the {leaflet} package (Cheng et al. 2024). You can zoom the map in/out and drag it around, and hovering over a polygon displays the name of the wildfire.
Interactive map of wildfires in Colorado. Source - HIFLD Open data
Quarry fire map
Finally I’ll isolate the Quarry fire burning southwest of Denver and show how you can easily jazz up the map with some nice features from the {leaflet} and {leaflet.extras} packages.
Some nice features you can add include:
Multiple basemaps that you can toggle between. To do this, you can add the group parameter in addProviderTiles(), and then use addLayersControl() to add a toggle button.
A scale bar is always helpful and can be added with addScaleBar()
A button to reset the map view to original with addResetMapButton()
An inset map showing the larger area with addMiniMap()
Code
# isolate the quarry firequarry<-co_fires|>filter(poly_Incid=="Quarry")leaflet()|>addProviderTiles(providers$Esri.WorldImagery, group ="Esri.WorldImagery")|>addProviderTiles(providers$OpenTopoMap, group ="OpenTopoMap")|>addPolygons(data =quarry, color ="red", weight =3, label ="Fire Perimeter")|>addMarkers(lat =quarry$attr_Initi, lng =quarry$attr_Ini_1, label ="Start Location")|>leaflet::setView(lat =quarry$attr_Initi, lng =quarry$attr_Ini_1, zoom =13)|># set initial viewleaflet::addScaleBar()|>leaflet.extras::addResetMapButton()|>leaflet::addMiniMap( position ="topright", tiles =providers$Esri.WorldStreetMap, toggleDisplay =TRUE, minimized =FALSE, zoomLevelFixed =8)|>addLayersControl( baseGroups =c("Esri.WorldImagery", "OpenTopoMap"),# toggle for layers on the topleft position ="topleft")
Interactive map of Quarry fire in Jefferson County, CO. Inset shows location of the main map relative to Denver.
Summary
I hope this post was interesting and gives you an idea of some ways you can get started working with and visualizing spatial data in R.
Cheng, Joe, Barret Schloerke, Bhaskar Karambelkar, and Yihui Xie. 2024. “Leaflet: Create Interactive Web Maps with the JavaScript ’Leaflet’ Library.”https://rstudio.github.io/leaflet/.
---title: "Mapping Colorado Wildfire Perimeters with R"date: 2024-08-04#date-modified: todayimage: screenshot.pngformat: html: code-link: true code-fold: show code-tools: true toc: true fig-width: 9 fig-height: 7 tbl-cap-location: bottomeditor: visualcategories: [R,leaflet,mapping,geospatial]freeze: autodraft: falsebibliography: references.bib---# IntroductionIn this blog post I'll show how you can use R to map and analyze spatial data on wildfires in the US and in Colorado, using packages like {[sf](https://r-spatial.github.io/sf/)} and {[leaflet](https://rstudio.github.io/leaflet/)}. As I write this, there are several major wildfires burning nearby along the Colorado Front Range (luckily they all seem to be [under control now](https://coloradosun.com/2024/08/04/live-colorado-wildfire-updates-sunday/)).## Getting the DataI downloaded the shapefiles for the [Best available perimeters for all known wildland fires in the United States](https://hifld-geoplatform.hub.arcgis.com/datasets/geoplatform::wfigs-interagency-fire-perimeters/about) from the [HIFLD Open website](https://hifld-geoplatform.hub.arcgis.com/pages/hifld-open) on August 6, 2024. HIFLD stands for *Homeland Infrastructure Foundation-Level Data*, and the [HIFLD Open website](https://hifld-geoplatform.hub.arcgis.com/pages/hifld-open) contains a lot of interesting spatial data sets for the US.## ::: callout-importantThis post is about how to work with spatial data in R, and not an up-to-date or official source of verified information about the fires. See also the following caveats from the data set:- *This data set is an ongoing project and as such, may be incomplete.*- *Currently only certified perimeters and new perimeters captured starting in 2021 are included.*:::After downloading the data and unzipping the file, the data can be read into R with the st_read() function from the {sf} package [@sf]. The output gives some information about the spatial data including the coordinate reference system and bounding box.```{r}#| label: load libraries and read data#| message: falselibrary(sf) # read and work with spatial datalibrary(tidyverse) library(leaflet) # mappinglibrary(leaflet.extras)shpfile <- ('./data/WFIGS_Interagency_Perimeters_-8845918407708086874/Perimeters.shp')fires <- sf::st_read(shpfile)```The data contains a *lot* (111) of fields in addition to the geometry:```{r}names(fires)```The data we read with st_read() is actually a *sf* and *data.frame* object, which we can see if we look at its class. *sf* stands for [Simple Features](https://en.wikipedia.org/wiki/Simple_Features), a standard for storing spatial features like points, lines, and polygons. The spatial features are stored in a column of the data frame named *geometry*.```{r}class(fires)```Since it is a data frame we can filter the data using standard methods like {dplyr}. I filtered the data to fires in Colorado using the *attr_POOOSt* column (I assume that the *POOSt* stands for Point of Origin State). I also limited the data to fires greater than 200 acres in size.```{r}co_fires <- fires |>filter(attr_POOSt =="US-CO") |>filter(poly_Acres >200)rm(fires)#co_fires```If we want to see the top 20 fires by size (acres), we can filter and arrange the data frame using {dplyr}. The 9th fire on the list is the [Alexander Mountain Fire](https://coloradosun.com/2024/08/01/alexander-mountain-fire-structures-burned/), one of the several fires currently burning.- Note that the largest fires are not always the most destructive; an obvious example is the [Marshall Fire](https://en.wikipedia.org/wiki/Marshall_Fire) which is 14th on this list but was extremely destructive.::: callout-noteThe st_drop_geometry() function from {sf} allows you to drop the geometry column from a sf/data.frame object so you can work with a simple data frame that is smaller in size.:::```{r}#| label: fig-top20-fires#| fig-cap: Figure showing top 20 Colorado wildfires by size (acres).co_fires |> sf::st_drop_geometry() |>slice_max(order_by = poly_Acres, n =20) |>ggplot(aes(poly_Acres, y =reorder(poly_Incid, poly_Acres))) +geom_col(fill ="red", color ="red", width =0.8) +labs(x ="Size [Acres]",y =NULL,title ="20 Largest Wildfires in Colorado",caption ="Data source: WFIGS Interagency Fire Perimeters") +scale_x_continuous(labels = scales::comma) +# add commas to axes labelstheme_minimal()```## Plotting a map of Colorado firesThe data can easily be visualized on an interactive map using the {leaflet} package [@leaflet]. You can zoom the map in/out and drag it around, and hovering over a polygon displays the name of the wildfire.```{r}#| label: map-co-fires#| fig-cap: Interactive map of wildfires in Colorado. Source - HIFLD Open dataleaflet() |>addTiles() |>addPolygons(data = co_fires, label =~poly_Incid, color ="red", weight =2) ```## Quarry fire mapFinally I'll isolate the [Quarry fire](https://coloradosun.com/2024/07/31/wildfire-jefferson-county-deer-creek-canyon/) burning southwest of Denver and show how you can easily jazz up the map with some nice features from the {leaflet} and {leaflet.extras} packages.Some nice features you can add include:- Multiple basemaps that you can toggle between. To do this, you can add the *group* parameter in addProviderTiles(), and then use addLayersControl() to add a toggle button.- A scale bar is always helpful and can be added with addScaleBar()- A button to reset the map view to original with addResetMapButton()- An inset map showing the larger area with addMiniMap()```{r}#| label: map-quarry#| fig-cap: Interactive map of Quarry fire in Jefferson County, CO. Inset shows location of the main map relative to Denver. # isolate the quarry firequarry <- co_fires |>filter(poly_Incid =="Quarry")leaflet() |>addProviderTiles(providers$Esri.WorldImagery, group ="Esri.WorldImagery") |>addProviderTiles(providers$OpenTopoMap, group ="OpenTopoMap") |>addPolygons(data = quarry, color ="red", weight =3, label ="Fire Perimeter") |>addMarkers(lat = quarry$attr_Initi, lng = quarry$attr_Ini_1, label ="Start Location") |> leaflet::setView(lat = quarry$attr_Initi, lng = quarry$attr_Ini_1, zoom =13) |># set initial view leaflet::addScaleBar() |> leaflet.extras::addResetMapButton() |> leaflet::addMiniMap(position ="topright",tiles = providers$Esri.WorldStreetMap,toggleDisplay =TRUE,minimized =FALSE,zoomLevelFixed =8 ) |>addLayersControl(baseGroups =c("Esri.WorldImagery", "OpenTopoMap"),# toggle for layers on the topleftposition ="topleft")```# SummaryI hope this post was interesting and gives you an idea of some ways you can get started working with and visualizing spatial data in R.# SessionInfo::: {.callout-tip collapse="true"}## Expand for Session Info```{r, echo = FALSE}sessionInfo()```:::# References