Skip to content

Instantly share code, notes, and snippets.

@peterdalle
Created February 2, 2025 11:04
Show Gist options
  • Save peterdalle/144b7f12353f1ec37cff43adf66262b9 to your computer and use it in GitHub Desktop.
Save peterdalle/144b7f12353f1ec37cff43adf66262b9 to your computer and use it in GitHub Desktop.
Race Laws in South Africa: 317 laws and when they were introduced and repealed, 142 laws still operative
library(rio)
library(tidyverse)
library(stringr)
library(ggtext) # For richtext (Unicode text handling)
# https://racelaw.co.za/index-of-race-law/
url <- "https://racelaw.co.za/wp-content/uploads/2025/01/2025-01-09-Index-of-Race-Law.xlsx"
index_version <- "9 January 2025"
df_raw <- import(url)
df <- df_raw |>
mutate(i = row_number(),
i_rev = rev(i),
year = as.numeric(Year),
status = as.factor(case_when(
str_detect(`Operative Status`, "Repealed") ~ "Repealed",
str_detect(`Operative Status`, "Operative") ~ "Operative")),
law = as.factor(case_when(
str_detect(`Race Law Status`, "Racialised") ~ "Racialized",
str_detect(`Race Law Status`, "Deracialised") ~ "Deracialized",
TRUE ~ `Race Law Status`)),
repealed_year = if_else(status == "Repealed", as.numeric(str_extract(`Operative Status`, "\\d{4}")), NA),
start_date = as_date(paste0(year, "-01-01")),
end_date = as_date(if_else(is.na(repealed_year), as.character(Sys.Date()), paste0(repealed_year, "-01-01"))),
)
n_operative_laws <- sum(df$status == "Operative")
themify <- function(base_size = 30) {
theme_classic() +
theme(
text = element_text(size = base_size),
plot.margin = margin(5, 5, 5, 5, "mm"),
plot.title = element_text(size = base_size + 27, face = "bold", hjust = .5),
plot.subtitle = element_text(size = base_size + 5, color = "#777", face = "plain", hjust = .5, margin = margin(b = 25)),
plot.caption = element_text(color = "#777", size = base_size - 4),
axis.line.y = element_blank(),
axis.text = element_text(size = base_size),
axis.ticks.length.x = unit(3, "mm"),
axis.ticks.y = element_blank(),
axis.title.y = element_blank(),
legend.position = "inside",
legend.position.inside = c(.2, .3),
legend.background = element_rect(fill = "#eee"),
legend.key.size = unit(12, "mm"),
legend.key.width = unit(12, "mm"),
legend.key = element_rect(linewidth = 0, fill = "transparent"),
legend.title = element_text(size = 20, face = "bold"),
legend.text = element_text(size = 20)
)
}
colors <- c("#89CBEC", "#147635", "#CB6878", "#A94698") # Color-blind palette
df |>
ggplot() +
geom_vline(aes(xintercept = as.Date("1994-01-01")), alpha = 0.2) +
geom_segment(aes(x = start_date, xend = end_date, y = i_rev, yend = i_rev, color = law), linewidth = .6) +
scale_x_date(date_breaks = "10 year", date_labels = "%Y") +
scale_y_continuous(labels = NULL) +
scale_color_manual(values = colors) +
annotate("richtext", size = 5, x = as.Date("1976-01-01"), y = max(df$i) + 10, color = "#666", label.color = NA, label = "&larr; Pre-Democratic Era") +
annotate("richtext", size = 5, x = as.Date("2009-01-01"), y = max(df$i) + 10, color = "#666", label.color = NA, label = "Democratic Era &rarr;") +
themify(base_size = 14) +
labs(title = "Race Laws in South Africa",
subtitle = glue::glue(
"{NROW(df)} laws and when they were introduced and repealed\n",
"{n_operative_laws} laws still operative"),
caption = paste0(
"\nGraphics: Peter M. Dahlgren (https://peterdahlgren.com)",
"\nSource: Index of Race Law from the South African Institute of Race Relations, IRR (https://racelaw.co.za/index-of-race-law/)",
"\nIndex version: ", index_version),
alpha = "Status of Law",
color = "Type of Law",
x = NULL,
y = NULL) +
guides(color = guide_legend(override.aes = list(linewidth = 5)))
ggsave("race-laws-south-africa.pdf", width = 210, height = 297, units = "mm", scale = 1, device = cairo_pdf, family = "DejaVu Sans")
ggsave("race-laws-south-africa.png", width = 210, height = 297, units = "mm", scale = 1)
@peterdalle
Copy link
Author

race-laws-south-africa

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment