Create 3D County Maps Using Density as Z-Axis
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
This is going to be a bit longer than some of my previous tutorials as it covers a walkthrough for sourcing data, scraping tables, cleaning, and generating the 3D view below which you can springboard from with the help of the rgl
package. The heavy lifting is done with ggplot
and rayshader
.
Rayshader
rayshader is an open source R package for producing 2D and 3D hillshaded maps of elevation matrices using a combination of raytracing, spherical texture mapping, and ambient occlusion.
This amazing package is what inspired this tutorial. I saw one of the author’s tweets, remembered the 3D map from BlueShift I saw from the 2016 election results.
One thing to keep in mind is this will not be as fast as some other solutions (plotly for example), and the interactive element will likely not be shareable. There is a function called writeWebGL
within rgl that I have not had much luck with, but it does exist. Rasyshader allows for creating programatic flyovers and animations though.
The R Script
Including packages
These are the packages I used for the majority of the code. I will include the ones for creating rasters and rayshading later in this write-up.
library(ggplot2) library(ggmap) library(maps) library(mapdata) library(stringr) library(dplyr) library(rvest) library(magrittr) library(ggthemes)
County Information
This tutorial is for Minnesota, but other regions can be used without changing too much. The biggest difference I noticed was abbreviations for county names.
usa <- map_data("usa") states <- map_data("state") mn_df <- subset(states, region == "minnesota") counties <- map_data("county") mn_county <- subset(counties, region == "minnesota") mn_county$pos <- 1:nrow(mn_county)
The dataframe mn_county
will be reused as the primary dataframe in this tutorial, and will have information from difference sources appended to this dataframe.
Population Information
webpage <- read_html("https://en.wikipedia.org/wiki/List_of_counties_in_Minnesota") tbls <- html_nodes(webpage, "table") # Shows all tables tbls
We only need one table. To determine which table we print out the table. It is the one with sortable in the class name, but there are other ways of determining which one. The results from tbls
will give something that looks like this…
{xml_nodeset (3)} [1]