Fancy Maps
This week, we’ll make our maps zoom-able and interactive with the
leaflet
package.
Here’s a demonstration, plotting the county-level 2020 presidential election results for each county in Georgia.1 First, load all the packages we need:
Next, we’ll get our map data from the tigris
package.
The format of this data is called a Simple Feature, or sf
object. It is a more compact way of representing GIS data, and is
quickly becoming the standard way to do things.
Simple feature collection with 6 features and 17 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -85.46221 ymin: 31.01044 xmax: -81.73169 ymax: 34.58748
Geodetic CRS: NAD83
STATEFP COUNTYFP COUNTYNS GEOID NAME NAMELSAD LSAD
16 13 189 00348794 13189 McDuffie McDuffie County 06
53 13 025 00351605 13025 Brantley Brantley County 06
54 13 171 00326713 13171 Lamar Lamar County 06
83 13 115 00353665 13115 Floyd Floyd County 06
102 13 273 00352238 13273 Terrell Terrell County 06
103 13 063 01672399 13063 Clayton Clayton County 06
CLASSFP MTFCC CSAFP CBSAFP METDIVFP FUNCSTAT ALAND AWATER
16 H1 G4020 <NA> 12260 <NA> A 666590014 23114032
53 H1 G4020 <NA> 15260 <NA> A 1147972258 10291563
54 H1 G4020 122 12060 <NA> A 475264404 6044329
83 H1 G4020 122 40660 <NA> A 1320404595 22414013
102 H1 G4020 <NA> 10500 <NA> A 869695791 4951325
103 H1 G4020 122 12060 <NA> A 366879097 6962586
INTPTLAT INTPTLON geometry
16 +33.4806126 -082.4795333 MULTIPOLYGON (((-82.44998 3...
53 +31.1973339 -081.9829779 MULTIPOLYGON (((-81.91012 3...
54 +33.0744405 -084.1466893 MULTIPOLYGON (((-84.24837 3...
83 +34.2636918 -085.2136851 MULTIPOLYGON (((-85.24134 3...
102 +31.7771909 -084.4394464 MULTIPOLYGON (((-84.56317 3...
103 +33.5426863 -084.3555727 MULTIPOLYGON (((-84.45856 3...
Notice that this may take a little while, because it’s downloading the shape data from the Census. Next we’ll merge that map data with the county-level election results.
# load data from project folder
load('../data/county-results-2020-for-map.RData')
# we're going to merge by fips code, so
# make sure that the fips code in each dataset
# is named the same thing and is in the same format
county_map <- mutate(county_map,
fips = as.numeric(GEOID))
counties_2020 <- mutate(counties_2020,
fips = as.numeric(county_fips))
# join the map data and the election results data together
d <- left_join(county_map, counties_2020, by = 'fips')
We can plot sf
objects with ggplot
using
the geom_sf()
layer.
# define the hex color codes for Democratic Blue and Republican Red
party_colors <- c("#CB454A", 'gray', "#2E74C0")
ggplot(data = d,
mapping = aes(fill = percent_biden)) +
geom_sf() +
scale_fill_gradient2(low = party_colors[1],
mid = party_colors[2],
high = party_colors[3],
midpoint = 50) +
theme_map() +
theme(legend.position = 'bottom') +
labs(fill = 'Biden Two-Party Vote Share')
And we can make an interactive map with leaflet()
. See
here
for instructions on modifying the color palette, and here
for the complete list of base maps you can add.
# create the color scheme
pal <- colorNumeric(
palette = party_colors,
domain = d$percent_biden)
p <- leaflet(data = d) %>%
# add the county polygons, with fill color based on Biden vote share and label with county name
addPolygons(fillColor = ~pal(percent_biden),
weight = 1,
opacity = 1,
color = 'white',
fillOpacity = 0.7,
label = d$NAME) %>%
# add a basemap
addProviderTiles(providers$Esri.WorldGrayCanvas) %>%
# add a legend
addLegend(pal = pal, values = ~percent_biden,
opacity = 0.7, title = NULL,
position = 'bottomright')
p
Next week, we discuss the challenges and opportunities presented by data that is collected across multiple time periods. To prepare, please read and annotate Chapter 16 of R For Data Science.
Revise your map from last week based on our in-class feedback. Submit
both a still image of your map from ggplot()
and create an
interactive version of the map with leaflet()
to show off
in class next week.
All the code is available on the
repository at
R/week-08/interactive-map-election-results-2020.R
.↩︎