Skip to content

Instantly share code, notes, and snippets.

@etachov
Created February 28, 2016 18:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save etachov/e5f97792f846023bfba8 to your computer and use it in GitHub Desktop.
Save etachov/e5f97792f846023bfba8 to your computer and use it in GitHub Desktop.
Make a timeline gif using ggplot, gganimate and ggrepel
### make a timeline gif of upcoming elections using data from IFES
library(ggplot2) # plotting engine
library(dplyr) # data manipulation
library(ggrepel) # smart plot labels
library(gganimate) # easy gif-making
library(lubridate) # dealing with date-time
library(RColorBrewer) # color scale
## read in the data from github
elect <- read.csv("https://raw.githubusercontent.com/etachov/election-feedr/master/upcoming_elections_sample.csv")
## make a string of key terms of representative elections - we'll use this later
reps <- "Representatives|Parliament|Council|Assembly|Congress|Senate|Chamber"
## add a simplified election type variable - it ain't pretty
elect_simple <- elect %>%
group_by(country, date) %>%
# if there more than one election in a country on a date, we'll categorize it as "Multiple"
mutate(type.simple = ifelse(n() > 1, "Multiple",
# next we'll use the list reps string to get the representative elections
ifelse(grepl(reps, elect.type), "Representative Body",
# president is simple
ifelse(grepl("President", elect.type), "Presidential",
# as is referendum
ifelse(grepl("Referendum", elect.type), "Referendum", "Other"))))) %>%
# pull distinct within the groups; this will remove the duplicates for countries that have multiple elections on one day
distinct(country) %>%
# ungroup before we mutate the dates
ungroup() %>%
mutate(date = ymd(date),
month_label = month(date, label = T))
## making the gif with ggplot2, gganimate and ggrepel
p <- ggplot(elect_simple, aes(x = date, y = 0, color = type.simple, label = country, frame = month(date))) +
# set up the line for the timeline
geom_hline(yintercept = 0, color = "lightgrey", size = 1, linetype = 2) +
# add points
geom_point(alpha = .7, size = 8) +
# use geom_label_repel to spread out the overlapping labels
# the box.padding label arguement pushes the labels away from the line
geom_label_repel(box.padding = unit(3, 'lines'),
segment.color = "lightgrey",
segment.size = 0.3,
size = 8,
alpha = .7,
# hide the legend for the label layer
show.legend = F) +
scale_color_brewer(type = "div", palette = "Set1") +
labs(title = "Upcoming Elections") +
# start with theme_minimal and makea a few tweaks
theme_minimal() +
theme(panel.grid = element_blank(),
axis.title = element_blank(),
axis.text.x = element_text(face = "italic", color = "#777777", size = 20),
axis.text.y = element_blank(),
plot.title = element_text(face = "bold", color = "#777777", size = 40, hjust = 0.5),
legend.position = "top",
legend.title = element_blank(),
legend.text = element_text(color = "#777777", size = 14))
gg_animate(p, filename = "upcoming_elections.gif", interval = 1.2, title_frame = F)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment