The following exercise is for Module 5 in Dr. Andreas Handel’s MADA Course.
I am recreating the first figure reflected in FiveThirtyEight’s article entitled, “The Rise of Terrorism Inspired By Religion In France.” It previous deaths due to terrorism in France as well as the European Union from 1972 - 2014. The following code is an additive process as each element of the figure is replicated.
Source article can be found here
The following R packages are required for this exercise:
The first step was to download the data from the FiveThirtyEight GitHub repository and import it.
#define path to EU data
<- here::here("data","eu_terrorism_fatalities_by_country.csv")
data_location_1
#load EU data
<- utils::read.csv(data_location_1, stringsAsFactors = FALSE) EU_rawdata
I first added a total fatalities column to the data, and then I converted it to the long format. It took a couple tries before I realized that I needed to convert the country columns to numeric, as they were imported as numeric. I then filtered the data to select only the France and total fatalities.
#create total column
<- EU_rawdata %>%
EU_processeddata ::mutate(Total = rowSums(.[2:13]))
dplyr
#look at structure of df
::str(EU_processeddata) utils
## 'data.frame': 45 obs. of 14 variables:
## $ iyear : int 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 ...
## $ Belgium : int 0 0 0 0 0 0 0 0 1 1 ...
## $ Denmark : int 0 0 0 0 0 0 0 0 0 0 ...
## $ France : int 0 0 1 5 3 3 7 3 21 11 ...
## $ Germany : int 0 0 0 0 0 0 0 0 0 0 ...
## $ Greece : int 2 0 0 5 92 1 14 1 0 1 ...
## $ Ireland : int 1 1 6 4 34 7 5 2 1 9 ...
## $ Italy : int 0 0 1 62 26 0 10 25 21 24 ...
## $ Luxembourg : int 0 0 0 0 0 0 0 0 0 0 ...
## $ Netherlands : int 0 0 0 1 1 4 0 9 1 3 ...
## $ Portugal : int 0 0 0 0 0 0 3 0 0 3 ...
## $ Spain : int 0 0 2 6 19 31 17 44 84 112 ...
## $ United.Kingdom: int 20 110 368 210 234 245 264 103 81 133 ...
## $ Total : num 23 111 378 293 409 291 320 187 210 297 ...
#need to convert all numeric columns to numeric (not integers)
2:13] <- lapply(EU_processeddata[,2:13], as.numeric)
EU_processeddata[,
#recheck structure of df
::str(EU_processeddata) utils
## 'data.frame': 45 obs. of 14 variables:
## $ iyear : int 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 ...
## $ Belgium : num 0 0 0 0 0 0 0 0 1 1 ...
## $ Denmark : num 0 0 0 0 0 0 0 0 0 0 ...
## $ France : num 0 0 1 5 3 3 7 3 21 11 ...
## $ Germany : num 0 0 0 0 0 0 0 0 0 0 ...
## $ Greece : num 2 0 0 5 92 1 14 1 0 1 ...
## $ Ireland : num 1 1 6 4 34 7 5 2 1 9 ...
## $ Italy : num 0 0 1 62 26 0 10 25 21 24 ...
## $ Luxembourg : num 0 0 0 0 0 0 0 0 0 0 ...
## $ Netherlands : num 0 0 0 1 1 4 0 9 1 3 ...
## $ Portugal : num 0 0 0 0 0 0 3 0 0 3 ...
## $ Spain : num 0 0 2 6 19 31 17 44 84 112 ...
## $ United.Kingdom: num 20 110 368 210 234 245 264 103 81 133 ...
## $ Total : num 23 111 378 293 409 291 320 187 210 297 ...
#set as data table
::setDT(EU_processeddata)
data.table
#convert to long format
<- data.table::melt(data = EU_processeddata,
EU_processeddata_long id.vars = "iyear",
variable.name = "country",
value.name = "fatalities")
#select only France and Total country values
<- dplyr::filter(EU_processeddata_long, country %in% c("France", "Total")) chart_data
The first visualization step was to create the default area chart generated by the ggplot2 package.
#with defaults only
::ggplot(chart_data, aes(x = iyear, y = fatalities, fill = country))+
ggplot2geom_area()
I started with adjusting the immediately obvious changes: reordering the categories, hiding the legend, adding a title, changing the background of the plot area, and changing the colors.
#reorder so France shows up on the bottom of stack
::ggplot(chart_data, aes(x = iyear, y = fatalities, fill = factor(country, levels = c("Total", "France"))))+
ggplot2geom_area()
#add title and hide legend
::ggplot(chart_data, aes(x = iyear, y = fatalities, fill = factor(country, levels = c("Total", "France")))) +
ggplot2geom_area(show.legend = FALSE) +
labs( x = "", y = "",
title ="Previous Terrorism Deaths in France And The EU",
subtitle = "Europen Union member countries as of 1986") +
theme(
plot.title = element_text(hjust = -0.15, vjust = 0, face = "bold"),
plot.subtitle = element_text(hjust = -0.1, vjust = 0))
#adjusting background of plot to match
::ggplot(chart_data, aes(x = iyear, y = fatalities, fill = factor(country, levels = c("Total", "France")))) +
ggplot2geom_area(show.legend = FALSE) +
labs( x = "", y = "",
title ="Previous Terrorism Deaths in France And The EU",
subtitle = "Europen Union member countries as of 1986") +
theme(
panel.grid.minor.x = element_blank(),
panel.grid.minor.y = element_blank(),
panel.grid.major = element_line(colour = "#cccccc"),
plot.background = element_rect(fill = "#EBEBEB"),
plot.title = element_text(hjust = -0.15, vjust = 0, face = "bold"),
plot.subtitle = element_text(hjust = -0.1, vjust = 0))
#change colors
::ggplot(chart_data, aes(x = iyear, y = fatalities, fill = factor(country, levels = c("Total", "France")))) +
ggplot2geom_area(show.legend = FALSE) +
scale_fill_manual(values = c("#ffa999","#ff2700")) +
labs( x = "", y = "",
title ="Previous Terrorism Deaths in France And The EU",
subtitle = "Europen Union member countries as of 1986") +
theme(
panel.grid.minor.x = element_blank(),
panel.grid.minor.y = element_blank(),
panel.grid.major = element_line(colour = "#cccccc"),
plot.background = element_rect(fill = "#EBEBEB"),
plot.title = element_text(hjust = -0.15, vjust=0, face = "bold"),
plot.subtitle = element_text(hjust = -0.1, vjust = 0))
This step adds the text overlay labels. The arrow was tricky to get right, and I never did figure out how they completed a filled head arrow instead of an open one. The masterminds at Stack Overflow were incredibly helpful as I looked through old answers to understand how to adjust the arrow.
#add France and EU labels
::ggplot(chart_data, aes(x = iyear, y = fatalities, fill = factor(country, levels = c("Total", "France")))) +
ggplot2geom_area(show.legend = FALSE) +
scale_fill_manual(values = c("#ffa999","#ff2700")) +
annotate("text", x = 1980, y = 50,
label = "France",
color = "#ff2700",
size = 4.5,
fontface = 2) +
annotate("text", x = 1989, y = 350,
label = "European \nUnion",
color = "#ffa999",
size = 4.5,
fontface = 2,
hjust = 0) +
labs( x = "", y = "",
title ="Previous Terrorism Deaths in France And The EU",
subtitle = "Europen Union member countries as of 1986") +
theme(
panel.grid.minor.x = element_blank(),
panel.grid.minor.y = element_blank(),
panel.grid.major = element_line(colour = "#cccccc"),
plot.background = element_rect(fill = "#EBEBEB"),
plot.title = element_text(hjust = -0.15, vjust=0, face = "bold"),
plot.subtitle = element_text(hjust = -0.1, vjust = 0))
#add Madrid train bombings label
::ggplot(chart_data, aes(x = iyear, y = fatalities, fill = factor(country, levels = c("Total", "France")))) +
ggplot2geom_area(show.legend = FALSE) +
scale_fill_manual(values = c("#ffa999","#ff2700")) +
annotate("text", x = 1980, y = 50,
label = "France",
color = "#ff2700",
size = 4.5,
fontface = 2) +
annotate("text", x = 1989, y = 350,
label = "European \nUnion",
color = "#ffa999",
size = 4.5,
fontface = 2,
hjust = 0) +
annotate("text", x = 2004, y = 255,
label = "2004 Madrid \ntrain bombings",
color = "black",
size = 4,
hjust = 0.5) +
geom_segment(aes(x = 2004, xend = 2004, y = 220, yend = 200),
color = "black",
arrow = arrow(length = unit(0.2, "cm"))) +
labs( x = "", y = "",
title ="Previous Terrorism Deaths in France And The EU",
subtitle = "Europen Union member countries as of 1986") +
theme(
panel.grid.minor.x = element_blank(),
panel.grid.minor.y = element_blank(),
panel.grid.major = element_line(colour = "#cccccc"),
plot.background = element_rect(fill = "#EBEBEB"),
plot.title = element_text(hjust = -0.15, vjust=0, face = "bold"),
plot.subtitle = element_text(hjust = -0.1, vjust = 0))
This proved to be the trickiest step. I considered using the scales library to automatically overlay the x-axis labels. However, date formatting will always be my Achilles’ heel in coding. I never managed to figure out how to convert the year variable to a date format that the scales library accepted. Instead, I just added new labels, adjusted the origin location, and fidgeted with the plot themes to make the final adjustments.
#fix axes
::ggplot(chart_data, aes(x = iyear, y = fatalities, fill = factor(country, levels = c("Total", "France")))) +
ggplot2geom_area(show.legend = FALSE) +
scale_fill_manual(values = c("#ffa999","#ff2700")) +
scale_y_continuous(expand = c(0, 0), limits = c(0, NA)) +
scale_x_continuous(breaks = seq(1970, 2014, by = 5),
labels = c("1970", "'75", "'80", "'85", "'90", "'95", "2000", "'05", "'10")) +
annotate("text", x = 1980, y = 50,
label = "France",
color = "#ff2700",
size = 4.5,
fontface = 2) +
annotate("text", x = 1989, y = 350,
label = "European \nUnion",
color = "#ffa999",
size = 4.5,
fontface = 2,
hjust = 0) +
annotate("text", x = 2004, y = 255,
label = "2004 Madrid \ntrain bombings",
color = "black",
size = 4,
hjust = 0.5) +
geom_segment(aes(x = 2004, xend = 2004, y = 220, yend = 200),
color = "black",
arrow = arrow(length = unit(0.2, "cm"))) +
labs( x = "", y = "",
title ="Previous Terrorism Deaths in France And The EU",
subtitle = "Europen Union member countries as of 1986") +
theme(
panel.grid.minor.x = element_blank(),
panel.grid.minor.y = element_blank(),
panel.grid.major = element_line(colour = "#cccccc"),
plot.background = element_rect(fill = "#EBEBEB"),
axis.line.x = element_line(color="#5b5e5f", size = 0.5),
axis.ticks.length = unit(0.25, "cm"),
axis.ticks = element_line(colour = "#cccccc"),
axis.text=element_text(size=12),
plot.title = element_text(hjust = -0.35, vjust=0, face = "bold", size = 16),
plot.subtitle = element_text(hjust = -0.15, vjust = 0, size = 14))
This is the final figure generated by the code to replicate FiveThirtyEight’s article.
::ggplot(chart_data, aes(x = iyear, y = fatalities, fill = factor(country, levels = c("Total", "France")))) +
ggplot2geom_area(show.legend = FALSE) +
scale_fill_manual(values = c("#ffa999","#ff2700")) +
scale_y_continuous(expand = c(0, 0), limits = c(0, NA)) +
scale_x_continuous(breaks = seq(1970, 2014, by = 5),
labels = c("1970", "'75", "'80", "'85", "'90", "'95", "2000", "'05", "'10")) +
annotate("text", x = 1980, y = 50,
label = "France",
color = "#ff2700",
size = 4.5,
fontface = 2) +
annotate("text", x = 1989, y = 350,
label = "European \nUnion",
color = "#ffa999",
size = 4.5,
fontface = 2,
hjust = 0) +
annotate("text", x = 2004, y = 255,
label = "2004 Madrid \ntrain bombings",
color = "black",
size = 4,
hjust = 0.5) +
geom_segment(aes(x = 2004, xend = 2004, y = 220, yend = 200),
color = "black",
arrow = arrow(length = unit(0.2, "cm"))) +
labs( x = "", y = "",
title ="Previous Terrorism Deaths in France And The EU",
subtitle = "Europen Union member countries as of 1986") +
theme(
panel.grid.minor.x = element_blank(),
panel.grid.minor.y = element_blank(),
panel.grid.major = element_line(colour = "#cccccc"),
plot.background = element_rect(fill = "#EBEBEB"),
axis.line.x = element_line(color="#5b5e5f", size = 0.5),
axis.ticks.length = unit(0.25, "cm"),
axis.ticks = element_line(colour = "#cccccc"),
axis.text=element_text(size=12),
plot.title = element_text(hjust = -0.35, vjust=0, face = "bold", size = 16),
plot.subtitle = element_text(hjust = -0.15, vjust = 0, size = 14))