Recreating FiveThirtyEight Voter Registrations Graph

Karol Orozco
3 min readDec 28, 2022

--

Let’s practice our visualization skills with ggplot2 and recreate the graph from the “Voter Registrations Are Way, Way Down During The Pandemic” article.

First, Let’s get and prepare the data


# Import data
vreg<-read.csv("https://raw.githubusercontent.com/fivethirtyeight/data/master/voter-registration/new-voter-registrations.csv",
header=TRUE)

# Level the Month variable so that its in the right order (ie not alphabetical)
vreg$Month<-factor(vreg$Month,
levels=c("Jan", "Feb", "Mar", "Apr", "May"))

### USE spread() FROM tidyr
vreg<-vreg%>%
spread(Year, New.registered.voters)

### RENAME THE COLUMNS
colnames(vreg)<-c("Jurisdiction", "Month", "Y2016", "Y2020")

### mutate() FROM dplyr()
vreg<-vreg%>%
mutate(change= Y2020-Y2016)%>%
mutate(Color = ifelse(change > 0,"#48E5E8", "#F56C6A"))

a<- function(change){number_format(accuracy = 1,
scale = 1/1000,
suffix = "K")(change)}
## 'data.frame':    53 obs. of  6 variables:
## $ Jurisdiction: chr "Arizona" "Arizona" "Arizona" "Arizona" ...
## $ Month : Factor w/ 5 levels "Jan","Feb","Mar",..: 1 2 3 4 1 2 3 4 1 2 ...
## $ Y2016 : int 25852 51155 48614 30668 87574 103377 174278 185478 17024 20707 ...
## $ Y2020 : int 33229 50853 31872 10249 151595 238281 176810 38970 20260 33374 ...
## $ change : int 7377 -302 -16742 -20419 64021 134904 2532 -146508 3236 12667 ...
## $ Color : chr "#48E5E8" "#F56C6A" "#F56C6A" "#F56C6A" ...

Now the graph

ggplot(vreg, aes(x= Month, y= change, fill = Color))+
geom_col()+
geom_hline( yintercept = 0, color= "black")+

geom_rect(data = data.frame(Jurisdiction = "Arizona"),
aes(xmin = 4.5, xmax= 5.5, ymin= -Inf, ymax = Inf),
color = "lightgrey",
fill = "white",
alpha = 0,
linetype = "dotted",
inherit.aes = FALSE)+
geom_rect(data = data.frame(Jurisdiction = "California"),
aes(xmin = 4.5, xmax= 5.5, ymin= -Inf, ymax = Inf),
color = "lightgrey",
fill = "white",
alpha = 0,
linetype = "dotted",
inherit.aes = FALSE)+
geom_rect(data = data.frame(Jurisdiction = "Colorado"),
aes(xmin = 4.5, xmax= 5.5, ymin= -Inf, ymax = Inf),
color = "lightgrey",
fill = "white",
alpha = 0,
linetype = "dotted",
inherit.aes = FALSE)+
geom_rect(data = data.frame(Jurisdiction = "Delaware"),
aes(xmin = 4.5, xmax= 5.5, ymin= -Inf, ymax = Inf),
color = "lightgrey", fill = "white",
alpha = 0,
linetype = "dotted",
inherit.aes = FALSE)+
geom_rect(data = data.frame(Jurisdiction = "Florida"),
aes(xmin = 4.5, xmax= 5.5, ymin= -Inf, ymax = Inf),
color = "lightgrey",
fill = "white",
alpha = 0,
linetype = "dotted", inherit.aes = FALSE)+
geom_rect(data = data.frame(Jurisdiction = "Georgia"),
aes(xmin = 4.5, xmax= 5.5, ymin= -Inf, ymax = Inf),
color = "lightgrey",
fill = "white",
alpha = 0,
linetype = "dotted",
inherit.aes = FALSE)+
geom_rect(data = data.frame(Jurisdiction = "Illinois"),
aes(xmin = 4.5, xmax= 5.5, ymin= -Inf, ymax = Inf),
color = "lightgrey",
fill = "white",
alpha = 0,
linetype = "dotted",
inherit.aes = FALSE)+

facet_wrap(~Jurisdiction, scales = "free_y")+

scale_fill_identity(guide= FALSE)+
scale_x_discrete(limits=c("Jan", "Feb", "Mar", "Apr", "May"),
breaks=c("Jan","May"))+
scale_y_continuous(labels = label_number_si(a =! 0), n.breaks = 4)+

labs(
x="",
y="",
title = "Voter registration dropped dramatically during the pandemic",
subtitle = "Difference in the number of newly registered voters for each month in 2020 compared to the same month in 2016",
caption = "Some states treat voters who move between counties within a state as new registrants because they're unregistered from their old county and nearly registered in the new ones. ",

tag= "FiveThirtyEight") +

theme_classic()+
theme(
axis.line.y=element_blank(),
axis.line.x = element_blank(),
axis.ticks = element_blank(),
axis.text.y = element_text(size = 6.5, color = "gray"),
axis.text.x = element_text(size= 6.5, color = "gray"),


plot.title = element_text(size =9, face = "bold", hjust = 0.55),
plot.title.position = "plot",
plot.subtitle= element_text(size = 8, hjust = 0.55),

plot.caption = element_text(hjust = 0, size = 6, color = "grey50",
margin = margin(r=5)),
plot.background = element_rect(fill= "white"),
plot.tag.position = "bottom",
plot.tag = element_text(size= 5, color = "gray", hjust =0.1,
margin=margin(t=1,
r=5,
b=1,
l=20,
unit="pt")),
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_line(size= 0.1, color= "lightgrey",
linetype= "solid"),
panel.background = element_rect(fill = "white"),
panel.border = element_blank(),
panel.spacing = unit(1, "lines"),

strip.background= element_rect(fill= "white", linetype = "blank"),
strip.text = element_text(color= "black", face= "bold"),
strip.text.x = element_text(face = "bold", size= 7),


legend.title = element_blank(),
legend.position = "none"

)

Here is the result

--

--

Karol Orozco

MS in Data Science Candidate- Interest in Business Strategy | Partnership Management | Marketing Analytics | People + Data Justice | Project Management | Latinx