I’m a big fan of W E Du Bois’s data visualizations, as celebrated recently in Baptiste and Rusert’s, ‘W E B Du Bois’s Data Portraits’.

Many of the charts he and his students made seem to defy modern data viz categorisation and break ‘the rules’ — which makes them really refreshing.

So I thought I’d have a go at recreating some of my favourites in R.

Plot 1: Illiteracy

Original

ggplot

# Create tibble with data
pct <- c(99, 92.1, 81.6, 67.27, 50)
df <- tibble(pct) %>%
  mutate(xend = -100,
         m_pct = - pct)

# Create vectors of plot labels
year_label <- c("(1900?)", "1890", "1880", "1870", "1860")
pct_label <- c("99%", "92.1%", "81.6%", "67.27%", "(50%?)")

# Plot
ggplot(df) + 
  # Vertical bars
  geom_bar(aes(x = -pct, y = pct), stat = "identity", width = 1.89, fill = "black") +
  # Horizontal black bars (the "outline")
  geom_segment(aes(x = m_pct, y = pct, xend = xend, yend = pct), 
               stat = "identity", size = 9.2, colour = "black", lineend = "square") +
  # Horizontal white bars (the "fill")
  geom_segment(aes(x = m_pct, y = pct, xend = xend, yend = pct), 
               stat = "identity", size = 9, colour = "white", lineend = "square") +
  # x axis labels
  scale_x_continuous(breaks = -pct, 
                     limits = c(-103, -45), 
                     label = pct_label,
                     expand=c(0,0),
                     name = str_wrap("PERCENT OF ILLITERACY.", 10)) +
  # y axis labels
  scale_y_continuous(breaks = c(50, 67.27, 81.6, 92.1, 99), 
                     limits = c(0, 103),
                     label = year_label,
                     expand=c(0,0)) +
  # Modify theme
  theme(plot.margin = margin(20, 40, 20, 40),
        text = element_text(family = "Rajdhani", size = 16, colour = "black"),
        plot.title = element_text(size = 24, hjust = 0.5, face = "bold", margin = margin(0,0,10,0)),
        axis.title.x = element_text(hjust = -0.1, vjust = 14),
        panel.background = element_blank(),
        panel.grid = element_blank(),
        axis.title.y = element_blank(),
        axis.ticks = element_blank()) +
  # Add title
  labs(title = "ILLITERACY.")

Plot 2: Enrollment

Original

ggplot

# Create dataframe
year <- c("1860", "1870", "1878", "1884", "1888", "1891", "1897")
number <- c(7, 10351, 72655, 110150, 120533, 156836, 180565)
number_labels <- c("7", "10,351", "73,655", "110,150", "120,533", "156,836", "180,565")
df <- tibble(year, number, number_labels)  

# Plot
ggplot(df) +
  geom_bar(aes(x = year, y = -number), stat = "identity", width = 0.3, fill = "dark grey") + 
  scale_x_discrete(position = "top") +
  geom_text(aes(x = year, y = (-number -3000)), label = number_labels, family = "Rajdhani", size = 5) +
  theme(text = element_text(family = "Rajdhani", colour = "black"),
        panel.background = element_blank(),
        axis.title = element_blank(),
        axis.text.x = element_text(size = 16),
        axis.text.y = element_blank(),
        axis.ticks = element_blank(),
        panel.grid = element_blank(),
        plot.title = element_text(size = 24, hjust = 0.5, face = "bold", margin = margin(0,0,30,0))) +
  labs(title = "NEGRO CHILDREN ENROLLED 
IN THE PUBLIC SCHOOLS.") 

Plot 3: Occupations

Original

ggplot

# Create tibble with data
race <- c("N", "W")
domestic_service <- c(28, 5.5)
agriculture <- c(62, 64)
manufacturing <- c(5, 13.5)
trade <- c(4.5, 13)
professions <- c(0.5, 4)
empty <- c(70, 70)

df <- tibble(race, empty, domestic_service, agriculture, manufacturing, trade, professions) %>% 
  gather(occupation, value, 2:7) %>% 
  mutate(order = paste(race, occupation)) %>% 
  mutate(number_labels = str_c(value, "%"))

# Create factor to order occupations
df$order <- factor(df$order, levels = c("N agriculture", "N domestic_service", "N manufacturing", 
                                            "N trade", "N professions", "N empty",
                                            "W agriculture", "W domestic_service", "W manufacturing", 
                                            "W trade", "W professions", "W empty", ordered = TRUE))

# Create vector for colours
occupation_fill <- c("agriculture" = "#EE3B3B",
                     "domestic_service" = "#FFD700",
                     " " = "white",
                     "manufacturing" = "#1C86EE",
                     "professions" = "#CDAA7D",
                     "trade" = "#EEEEE0")

# Create labels and breaks (items to appear in Key) for occupations
occupation_labels <- c("agriculture" = "AGRICULTURE, FISHERIES AND MINING.",
                       "manufacturing" = "MANUFACTURING AND MECHANICAL INDUSTRIES.",
                       "domestic_service" = "DOMESTIC AND PERSONAL SERVICE.",
                       "professions" = "PROFESSIONS.",
                       "trade" = "TRADE AND TRANSPORTATION.")

occupation_breaks <- c("agriculture", "manufacturing", "domestic_service", "professions", "trade")

# Plot
ggplot(df) +
  geom_bar(aes(x = "", y = value, fill = occupation, group = order), stat = "identity") +
  geom_text(aes(x = "", y = 285, vjust = -18, label = "NEGROES."), family = "Rajdhani", size = 5) +
    geom_text(aes(x = "", y = 120, vjust = 19, label = "WHITES."), family = "Rajdhani", size = 5) +
  coord_polar("y", start = 5.3, direction = 1) +
  scale_y_reverse() +
  scale_fill_manual(values = occupation_fill, 
                    labels = occupation_labels,
                    breaks = occupation_breaks,
                    guide = guide_legend(title = NULL, ncol = 2)) +
  theme_minimal() +
  theme(text = element_text(family = "Rajdhani", size = 16, colour = "black"),
        plot.title = element_text(size = 24, hjust = 0.5, face = "bold", margin = margin(0,0,10,0)),
        panel.background = element_blank(),
        panel.grid = element_blank(),
        axis.text = element_blank(),
        axis.title = element_blank(),
        axis.ticks = element_blank(),
        legend.position = "bottom") +
  labs(title = "OCCUPATIONS OF NEGROES AND WHITES IN GEORGIA.")