Using ggplot2 to display the revised change in US Jobs Numbers for May and June (CC367)
This summer the US Bureau of Labor Statistics revised their projections for the number of jobs created in in May and June. The New York Times had an interesting visualization of the data. I decided to recreate the original using R, readxl, ggplot2, and other tools from the tidyverse. The functions I used from these packages include aes, annotate, arrange, as.character, bind_rows, c, element_blank, element_line, element_text, factor, filter, font_add_google, function, geom_col, ggplot, ggsave, if_else, labs, lag, library, margin, month, mutate, pivot_longer, position_identity, read_excel, rename, scale_color_manual, scale_fill_manual, scale_x_discrete, scale_y_continuous, select, showtext_auto, showtext_opts, theme, tibble, unit, and ymd. The newsletter describing this visualization at a 30,000 ft view can be found here. You can find the original article presenting the figure 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!
You can download the xlsx workbook from this episode here.
Want more practice on the concepts covered in Code Club? You can sign up for my weekly newsletter at https://shop.riffomonas.org/youtube to get practice problems, tips, and insights. If you’re interested in purchasing a video workshop be sure to check out https://riffomonas.org/workshops/
Support Riffomonas by becoming a Patreon member! https://www.patreon.com/riffomonas
You can also find complete tutorials for learning R with the tidyverse using… Microbial ecology data: https://www.riffomonas.org/minimalR/ General data: https://www.riffomonas.org/generalR/
If you want to cite this video, please consider citing https://journals.asm.org/doi/10.1128/mra.01310-22
library(tidyverse)
library(readxl)
library(scales)
library(showtext)
font_add_google("Libre Franklin", "franklin", bold.wt = 500)
showtext_opts(dpi = 300)
showtext_auto()
parse_month <- function(x) {
month(x, abbr = TRUE, label = TRUE)
}
read_excel("SeriesReport-20250827091254_d212f6.xlsx",
range = "A13:M24") %>%
pivot_longer(-Year, values_to = "number_of_jobs", names_to = "month") %>%
rename(year = Year) %>%
mutate(new_jobs = number_of_jobs - lag(number_of_jobs),
date = ymd(paste(year, month, 1, sep = "-")),
type = if_else(date != "2025-07-01", "real", "july")) %>% #lubridate
filter(date >= "2024-07-01" & date <= "2025-07-01") %>%
bind_rows(
tibble(year = c(2025, 2025),
month = c("May", "June"),
date = ymd("2025-05-01", "2025-06-01"),
new_jobs = c(144, 147),
type = "preliminary")
) %>%
select(date, new_jobs, type) %>%
mutate(type = factor(type, levels = c("preliminary", "real", "july")),
date = as.character(date)) %>%
arrange(date, type) %>%
ggplot(aes(x = date, y = new_jobs, fill = type, color = type)) +
geom_col(position = position_identity(), linewidth = 0.3, alpha = 0.9) +
annotate(
geom = "text", hjust = -0.05, family = "franklin",
x = -0.4, y = c(108, 208, 308),
label = c("+100,000", "+200,000", "+300,000"),
size = 8.5, size.unit = "pt", color = "gray40") +
annotate(
geom = "label",
x = c(11.5, 7.75, 13.5),
y = c(95, 200, 270),
label = c("REVISED\nDOWN", "Growth in May and\nJune was lower than\ninitially estimated.", "+73,000 jobs\nin July"),
hjust = c(0.5, 0, 1),
color = c("gray40", "black", "black"),
fontface = c("bold.italic", "bold", "bold"),
vjust = 0.5, alpha = 0.8, lineheight = 1,
label.size = 0, label.padding = unit(0, "pt"), family = "franklin",
size = 9, size.unit = "pt"
) +
annotate(
geom = "segment",
x = 13, y = 73, yend = 240, linewidth = 0.4
) +
annotate(
geom = "curve",
x = 10.9, xend = 11.5, y = 180, yend = 155,
linewidth = 0.4, curvature = -0.5
) +
scale_fill_manual(
breaks = c("preliminary", "real", "july"),
values = c("#FFFFFF", "gray70", "#FE8918")
) +
scale_color_manual(
breaks = c("preliminary", "real", "july"),
values = c("#BDBDBD", "#BDBDBD", "#FE8918")
) +
scale_x_discrete(
breaks = c("2024-07-01", "2024-09-01", "2024-11-01",
"2025-01-01", "2025-03-01", "2025-05-01", "2025-07-01"),
# labels = parse_month
labels = c("July '24", "Sept.", "Nov.",
"Jan. '25", "March", "May", "July")
) +
scale_y_continuous(expand = c(0, 0)) +
labs(
title = "Monthly change in jobs",
caption = "Source: Bureau of Labor Statistics • Note: Data is seasonally adjusted. • By Christine Zhang/Pat Schloss"
) +
theme(
text = element_text(family = "franklin"),
panel.background = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.major.y = element_line(color = "gray", linewidth = 0.4,
linetype = "12"),
axis.line.x = element_line(linewidth = 0.3),
axis.ticks = element_blank(),
axis.title = element_blank(),
axis.text.x = element_text(color = "black"),
axis.text.y = element_blank(),
legend.position = "none",
plot.title = element_text(color = "gray40", size = 10, face = "bold",
margin = margin(l = -15, b = 10)),
plot.caption = element_text(color = "gray40", size = 8, hjust = 0,
face = "bold",
margin = margin(t = 10, l = -15)),
plot.margin = margin(t = 8, r = 15, b = 8, l = 20)
)
ggsave("jobs_numbers.png", width = 6, height = 3.6)