Last active
December 7, 2024 14:45
-
-
Save USMortality/8e8f3244cb511922d44e6c909c0da02e to your computer and use it in GitHub Desktop.
Popular Vote Presidential Elections [USA]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(ggplot2) | |
library(scales) | |
library(dplyr) | |
# https://decisiondeskhq.com/results/2024/General/President/ | |
# https://election.lab.ufl.edu/2024-general-election-turnout/ | |
# https://www.google.com/search?q=us+elections | |
# Scale factor and plot dimensions | |
sf <- 2 | |
width <- 600 * sf | |
height <- 335 * sf | |
options(vsc.dev.args = list(width = width, height = height, res = 72 * sf)) | |
# Define party colors | |
party_colors <- c( | |
"Democrat" = "#1f78b4", # blue | |
"Republican" = "#e31a1c" # red | |
) | |
# Define variables | |
total_ballots <- 156252813 | |
harris_votes <- 74969829 | |
trump_votes <- 77258241 | |
other_votes <- 782243 + 755131 + 640903 + 388712 | |
outstanding <- total_ballots - harris_votes - trump_votes - other_votes | |
# Calculate reported and projected votes | |
harris_reported <- harris_votes | |
trump_reported <- trump_votes | |
ratio <- harris_votes / (harris_votes + trump_votes) | |
harris_projected <- outstanding * ratio | |
trump_projected <- outstanding * (1 - ratio) | |
reporting <- 1 - (outstanding / total_ballots) | |
(trump_reported + trump_projected) / total_ballots | |
(harris_projected + harris_reported) / total_ballots | |
# Create main dataset | |
election_data <- data.frame( | |
Year = c( | |
2012, 2012, 2016, 2016, 2020, 2020, 2024, 2024, 2024, 2024 | |
), | |
Candidate = c( | |
"Obama", "Romney", "Clinton", "Trump", "Biden", "Trump", | |
"Harris (reported)", "Trump (reported)", "Harris (projected)", "Trump (projected)" | |
), | |
Party = c( | |
"Democrat", "Republican", "Democrat", "Republican", | |
"Democrat", "Republican", "Democrat", "Republican", "Democrat", "Republican" | |
), | |
Votes = c( | |
65915795, 60933504, 65853514, 62984828, 81283501, 74223975, | |
harris_reported, trump_reported, harris_projected, trump_projected | |
), | |
Type = c( | |
"reported", "reported", "reported", "reported", "reported", "reported", | |
"reported", "reported", "projected", "projected" | |
) | |
) | |
# Order factor levels and data for stacking | |
election_data$Type <- factor(election_data$Type, levels = c("reported", "projected")) | |
election_data <- election_data[order(election_data$Year, election_data$Type), ] | |
# Summing up 2024 votes by Party | |
totals_2024 <- election_data %>% | |
filter(Year == 2024) %>% | |
group_by(Party) %>% | |
summarise(TotalVotes = sum(Votes)) %>% | |
mutate(total_text = paste0(comma(TotalVotes), "\n", percent(TotalVotes / total_ballots, accuracy = 0.01), "%")) | |
# Add `total_text` column to the main dataset for 2024 "projected" rows | |
election_data$total_text <- NA | |
election_data$total_text[election_data$Year == 2024 & election_data$Type == "projected"] <- | |
totals_2024$total_text | |
# Generate plot | |
chart <- ggplot(election_data, aes(x = Party, y = Votes, fill = Party)) + | |
geom_bar( | |
stat = "identity", | |
position = position_stack(reverse = TRUE), | |
aes(alpha = Type) | |
) + | |
geom_text( | |
aes(label = comma(round(Votes))), | |
position = position_stack(vjust = -1), | |
size = 3, | |
color = "white", | |
fontface = "bold" | |
) + | |
geom_text( | |
aes(label = total_text), | |
inherit.aes = TRUE, | |
na.rm = TRUE, | |
position = position_stack(vjust = 6.5), | |
size = 3.5, | |
color = "black", | |
fontface = "bold" | |
) + | |
scale_fill_manual(values = party_colors) + | |
scale_alpha_manual( | |
values = c("reported" = 1, "projected" = 0.6), | |
name = "Vote Type", | |
labels = c("Reported", "Projected") | |
) + | |
facet_wrap(~Year, nrow = 1) + | |
labs( | |
title = "Popular Vote US Presidential Elections (Updated: 12/6/24 9:40pm)", | |
subtitle = paste0( | |
sprintf("%.1f%% reporting", reporting * 100), | |
" · Outstanding: ", comma(outstanding), " · @USMortality" | |
), | |
caption = paste0( | |
"Source: decisiondeskhq.com, election.lab.ufl.edu,", | |
" wikipedia.org, google.com" | |
), | |
x = "Party", | |
y = "Votes", | |
fill = "Party" | |
) + | |
scale_y_continuous(labels = comma, limits = c(0, 85000000)) + | |
theme_bw() + | |
theme( | |
legend.position = "top", | |
axis.text.x = element_blank(), | |
axis.ticks.x = element_line(color = "black") | |
) | |
# Save the plot | |
ggsave( | |
filename = "chart1.png", plot = chart, width = width, height = height, | |
units = "px", dpi = 72 * sf, device = grDevices::png, type = "cairo" | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment