I intend to recreate a dumbbell graph, as used in an Ipsos MORI article, showing changes in moral attitudes between two surveys taken thirty years apart.
Details of the surveys, including the methodology, may be viewed on the Ipsos MORI website.
First, we install the tidyverse and ggalt packages.
library(tidyverse)
library(readxl)
library(ggalt)
Next, we set the theme.
theme_clean <- theme_bw(base_family="Calibri") +
theme(legend.position = "top",
legend.title = element_text(size = 12),
legend.text = element_text(size = 12),
plot.title = element_text(size = 18, face = "bold"),
plot.subtitle = element_text(size = 12, face = "italic", margin = margin(b=12)),
plot.caption = element_text(size = 10),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank())
theme_set(theme_clean)
For brevity of our code, we should use a custom function.
percent_calc <- function(x) {
x <- paste0(x*100)
x
}
We upload the table from an Excel file. The factor code ensures the order in the graph remains what we have inputted, rather than alphabetically. The ‘sgn’ column will show 1 if the 2019 share is lower than or equal to 1989, or -1 otherwise.
Ipsos_MORI_df <- read_excel("Ipsos MORI British Moral Attitudes - 2019-10-28.xlsx",
sheet = "DATA")
Ipsos_MORI_df$Issue <- factor(Ipsos_MORI_df$Issue,
levels=rev(Ipsos_MORI_df$Issue))
Ipsos_MORI_df <- Ipsos_MORI_df %>% mutate(Sgn = sign(y1989 - y2019 + 0.005))
Finally, we create the graph. The upper geom_text labels write the respective years above the first dots. The lower geom_text labels write the shares (where 29% is shown as 29) to the left or right of each dot.
Ipsos_MORI_gg <- ggplot(Ipsos_MORI_df, aes(y=Issue, x=y1989, xend=y2019)) +
geom_dumbbell(size=3, color="#8AB0BD",
colour_x = "#EE7523",
colour_xend = "#6D3A5D",
dot_guide=FALSE) +
geom_text(data=filter(Ipsos_MORI_df,
Issue=="Soft drugs (e.g. Cannabis)"),
aes(x=y1989, y=Issue, label="1989"),
color="#EE7523", size=5, vjust=-2,
fontface="bold", family="Calibri") +
geom_text(data=filter(Ipsos_MORI_df,
Issue=="Soft drugs (e.g. Cannabis)"),
aes(x=y2019, y=Issue, label="2019"),
color="#6D3A5D", size=5, vjust=-2,
fontface="bold", family="Calibri") +
labs(x="", y="",
title = "Summary of changes in what Britain sees as immoral",
subtitle = "Here is a list of issues some people might think are immoral or morally wrong.\nWhich of them, if any, do you personally think are morally wrong?",
caption = "Source: Ipsos MORI/King's College London. 1989 study: 1,458 face-to-face interviews between 2-13 March 1989. 2019 study: 1,021 face-to-face interviews between 27 June - 9 July 2019.") +
scale_y_discrete(expand = c(0.09,0)) +
scale_x_continuous(labels = scales::percent_format(accuracy = 1),
limits = c(0,1)) +
geom_text(data=Ipsos_MORI_df,
aes(x=y1989, y=Issue, label=percent_calc(y1989)),
color="#EE7523", size=3,
hjust=-Ipsos_MORI_df$Sgn*2, family="Calibri") +
geom_text(data=Ipsos_MORI_df,
aes(x=y2019, y=Issue, label=percent_calc(y2019)),
color="#6D3A5D", size=3,
hjust=Ipsos_MORI_df$Sgn*2, family="Calibri")
This gives the following graph:
Ipsos_MORI_gg