Using ggplot2 to recreate a visual of perceptions of Trump's policies in LA from (CC362)
Pat recreates a faceted waffle chart from the Washington Post to show the responses to a survey asking people’s sentiments about the use of military to quell the LA protests using ggplot2. The plot was generated using functions from the tidyverse including the dplyr, ggplot2, ggimage, showtext, ggtext, and glue packages. The functions he uses from these packages include aes, ceiling, coord_cartesian, element_blank, element_markdown, element_textbox_simple, facet_wrap, factor, filter, font_add_google, function, geom_image, geom_jitter, ggplot, ggsave, glue, labs, library, map, margin, mutate, position_jitter, rep, round, scale_color_manual, scale_y_continuous, scale_y_reverse, seq, showtext_auto, showtext_opts, sum, theme, tibble, tribble, unit, and unnest. The newsletter describing this visualization at a 30,000 ft view can be found here. You can find the original article describing the ridgeline plot here. If you have a figure that you would like to see me discuss in a future newsletter and episode of Code Club, email me at pat@riffomonas.org!
Code
library(tidyverse)
library(showtext)
library(ggtext)
library(glue)
library(ggimage)
font_add_google("Libre Franklin", "franklin")
font_add_google("Playfair Display", "playfair")
showtext_opts(dpi = 300)
showtext_auto()
waffle_coordinates <- function(n, n_cols = 18){
n_rows <- ceiling(n / n_cols)
n_extras <- n - n_cols * (n_rows - 1)
row_indices <- c(rep(1:(n_rows - 1), each = n_cols),
rep(n_rows, n_extras))
start_extras <- (n_cols - n_extras) / 2 + 1
end_extras <- start_extras + n_extras - 1
col_indices <- c(rep(1:n_cols, times = n_rows - 1),
seq(start_extras, end_extras, 1))
tibble(x = rep(col_indices, 3),
y = rep(row_indices, 3))
}
data <- tribble(
~category, ~level, ~logo,
"support", 23 * 18 + 7, "wp_logo.png",
"unsure", 8 * 18 + 5, NA,
"oppose", 24 * 18 + 13, NA
) %>%
mutate(
percent = round(100 * level / sum(level), digits = 0),
label = glue("**{str_to_sentence(category)}**<br>{percent}%"),
label = factor(label, levels = label))
data %>%
mutate(positions = map(level, waffle_coordinates)) %>%
unnest(positions) %>%
ggplot(aes(x = x, y = y)) +
geom_jitter(aes(color = category), show.legend = FALSE,
position = position_jitter(width = 0.1, height = 0.1,
seed = 19760620)) +
geom_image(data = filter(data, category == "support"),
x = -1, y = 7.5, aes(image = logo), size = 0.12) +
facet_wrap(~label, nrow = 1) +
scale_color_manual(
breaks = c("support", "unsure", "oppose"),
values = c("#4A8F9B", "#A8A8A8", "#E6823D")
) +
scale_y_reverse() +
# scale_y_continuous(transform = "reverse") +
coord_cartesian(expand = FALSE, clip = "off",
xlim = c(0.5, 18.5),
ylim = c(25.5, 0.5)
) +
labs(
title = "Do you support or oppose Trump sending the National Guard and
Marines to respond to the L.A. protests?"
) +
theme(
plot.margin = margin(t = 5, r = 10, b = 5, l = 20),
axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank(),
panel.background = element_blank(),
strip.background = element_blank(),
panel.spacing.x = unit(10, "pt"),
strip.text = element_markdown(family = "franklin", lineheight = 1.3),
plot.title = element_textbox_simple(family = "playfair", face = "bold",
linetype = 1, linewidth = 0.25,
padding = margin(8, 8, 8, 10),
margin = margin(3, 0, 20, 0),
r = unit(15, "pt"), size = 19,
lineheight = 1.3,
width = 0.93, hjust = 0)
)
ggsave("la_waffle_plot.png", width = 6, height = 4.435)