---
title: "Mapping Guerry's Moral Statistics with Cheysson Palettes"
author: "Michael Friendly"
date: "`r Sys.Date()`"
output: 
  rmarkdown::html_vignette:
    toc: true
    toc_depth: 2 
vignette: >
  %\VignetteIndexEntry{Mapping Guerry's Moral Statistics with Cheysson Palettes}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.width = 8,
  fig.height = 7,
  fig.align = "center",
  warning = FALSE,
  message = FALSE
)
```

## Introduction

This vignette demonstrates how to create thematic (choropleth) maps using the `ggCheysson` package with André-Michel Guerry's pioneering data on moral statistics of France from 1833. This represents a fascinating combination of:

- **Historical data**: Guerry's groundbreaking social statistics from 1830s France
- **Historical cartography**: The visual style of Émile Cheysson's *Albums de Statistique Graphique* (1879-1897)
- **Modern tools**: R, ggplot2, and spatial data packages

Guerry (1802-1866) was among the first to use statistical maps to visualize social phenomena across regions. His major work predated Cheysson's work on the _Albums_, making this a fitting tribute to two pioneers of statistical graphics. In Guerry (1833), he displayed six thematic choropleth maps of France,
using a monochrome shading scheme. What if Guerry could have re-done his maps using Cheysson's style? 

## Required Packages

```{r packages}
library(ggCheysson)
library(ggplot2)
library(Guerry)      # Historical data on France
library(sf)          # Modern spatial data handling
library(ggpattern)   # For Cheysson-style hatching patterns
```

## Loading Fonts

```{r load-fonts, eval=FALSE}
# Load Cheysson fonts
load_cheysson_fonts(method = "showtext")
showtext::showtext_auto()
```

```{r load-fonts-actual, include=FALSE}
# Actual font loading (hidden from output)
if (requireNamespace("showtext", quietly = TRUE) &&
    requireNamespace("sysfonts", quietly = TRUE)) {
  load_cheysson_fonts(method = "showtext")
  showtext::showtext_auto()
  fonts_available <- TRUE
} else {
  fonts_available <- FALSE
}
```

## Preparing the Data

### Load and Examine Guerry's Data

```{r load-data}
# Load the dataset
data(Guerry, package = "Guerry")

# Key variables for mapping
vars_of_interest <- c("Crime_pers", "Crime_prop", "Literacy",
                      "Donations", "Infants", "Suicides")

# View summary
str(Guerry[, c("dept", "Department", vars_of_interest)])
```

### Load the Map

The `gfrance85` object is a SpatialPolygonsDataFrame. We'll convert it to an sf object for modern spatial handling.

```{r load-map}
# Load the map
data(gfrance85, package = "Guerry")

# Convert to sf object (simple features)
france_sf <- st_as_sf(gfrance85)

# Check structure
head(france_sf[, c("Department", "Region")])
```

### Join Data with Map

```{r prepare-data}
# Convert variables to ranks (since they're on different scales)
guerry_ranked <- Guerry
for (var in vars_of_interest) {
  guerry_ranked[[paste0(var, "_rank")]] <- rank(guerry_ranked[[var]], na.last = "keep")
}

# Join with spatial data
france_data <- merge(france_sf, guerry_ranked,
                     by = "Department",
                     all.x = TRUE)

# Check the join
cat("Departments in map:", nrow(france_sf), "\n")
cat("Departments with data:", sum(!is.na(france_data$Crime_pers)), "\n")
```

## Creating Choropleth Maps

### Crime Against Persons (Sequential Palette)

```{r map-crime-pers, fig.height=7, fig.width=8}
# Map of crimes against persons
p1 <- ggplot(france_data) +
  geom_sf(aes(fill = Crime_pers_rank), color = "black", linewidth = 0.3) +
  scale_fill_cheysson("1895_04", discrete = FALSE,
                      name = "Rank") +
  labs(
    title = "Crimes Against Persons",
    subtitle = "France, 1830s (ranked by department)",
    caption = "Data: André-Michel Guerry (1833)"
  ) +
  theme_cheysson_map() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12),
    legend.position = "right"
  )

print(p1)
```

### Property Crime (Different Sequential Palette)

```{r map-crime-prop, fig.height=7, fig.width=8}
p2 <- ggplot(france_data) +
  geom_sf(aes(fill = Crime_prop_rank), color = "black", linewidth = 0.3) +
  scale_fill_cheysson("1895_04", discrete = FALSE,
                      name = "Rank") +
  labs(
    title = "Crimes Against Property",
    subtitle = "France, 1830s (ranked by department)",
    caption = "Data: André-Michel Guerry (1833)"
  ) +
  theme_cheysson_map() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12),
    legend.position = "right"
  )

print(p2)
```

### Literacy (Grouped Palette)

```{r map-literacy, fig.height=7, fig.width=8}
# Create quintiles for discrete display
france_data$Literacy_quint <- cut(france_data$Literacy_rank,
                                  breaks = quantile(france_data$Literacy_rank,
                                                   probs = seq(0, 1, 0.2),
                                                   na.rm = TRUE),
                                  include.lowest = TRUE,
                                  labels = c("Lowest", "Low", "Medium", "High", "Highest"))

p3 <- ggplot(france_data) +
  geom_sf(aes(fill = Literacy_quint), color = "black", linewidth = 0.3) +
  scale_fill_cheysson("1881_04",
                      name = "Literacy\nQuintile",
                      na.value = "grey80") +
  labs(
    title = "Literacy Rates",
    subtitle = "Percent of military conscripts who can read & write (quintiles)",
    caption = "Data: André-Michel Guerry (1833)"
  ) +
  theme_cheysson_map() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 11),
    legend.position = "right"
  )

print(p3)
```

### Literacy with Cheysson Patterns

Now let's recreate the literacy map using Cheysson's signature hatching patterns combined with colors:

```{r map-literacy-pattern, fig.height=7, fig.width=8}
# Literacy with patterns - quintessential Cheysson style
p3b <- ggplot(france_data) +
  geom_sf_pattern(
    aes(fill = Literacy_quint,
        pattern_type = Literacy_quint,
        pattern_fill = Literacy_quint),
    pattern = "stripe",
    pattern_density = 0.3,
    pattern_spacing = 0.02,
    color = "black",
    linewidth = 0.4
  ) +
  scale_fill_cheysson_pattern("1881_04", na.value = "grey90") +
  scale_pattern_fill_cheysson("1881_04", na.value = "grey90") +
  scale_pattern_type_cheysson("1881_04") +
  labs(
    title = "Literacy Rates with Cheysson Patterns",
    subtitle = "Combining colors and hatching patterns (quintiles)",
    caption = "Data: André-Michel Guerry (1833)"
  ) +
  theme_cheysson_map() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 11),
    legend.position = "right"
  ) +
  guides(
    fill = guide_legend(title = "Literacy\nQuintile"),
    pattern_type = guide_legend(title = "Literacy\nQuintile"),
    pattern_fill = "none"
  )

print(p3b)
```

### Charitable Donations (Category Palette)

```{r map-donations, fig.height=7, fig.width=8}
# Create categories
france_data$Donations_cat <- cut(france_data$Donations_rank,
                                 breaks = quantile(france_data$Donations_rank,
                                                  probs = seq(0, 1, 0.25),
                                                  na.rm = TRUE),
                                 include.lowest = TRUE,
                                 labels = c("Low", "Medium-Low", "Medium-High", "High"))

p4 <- ggplot(france_data) +
  geom_sf(aes(fill = Donations_cat), color = "black", linewidth = 0.3) +
  scale_fill_cheysson("1883_04",
                      name = "Donations\nLevel",
                      na.value = "grey80") +
  labs(
    title = "Charitable Donations",
    subtitle = "Donations to the poor (quartiles)",
    caption = "Data: André-Michel Guerry (1833)"
  ) +
  theme_cheysson_map() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12),
    legend.position = "right"
  )

print(p4)
```

### Donations with Cheysson Patterns

The combination of colors and patterns was a hallmark of the Albums. Here's the donations map in authentic Cheysson style:

```{r map-donations-pattern, fig.height=7, fig.width=8}
# Donations with varied pattern types
p4b <- ggplot(france_data) +
  geom_sf_pattern(
    aes(fill = Donations_cat,
        pattern_type = Donations_cat,
        pattern_fill = Donations_cat),
    pattern = "stripe",
    pattern_density = 0.35,
    pattern_spacing = 0.025,
    color = "black",
    linewidth = 0.4
  ) +
  scale_fill_cheysson_pattern("1883_04", na.value = "grey90") +
  scale_pattern_fill_cheysson("1883_04", na.value = "grey90") +
  scale_pattern_type_cheysson("1883_04") +
  labs(
    title = "Charitable Donations with Hatching Patterns",
    subtitle = "Authentic Cheysson-style patterns and colors (quartiles)",
    caption = "Data: André-Michel Guerry (1833)"
  ) +
  theme_cheysson_map() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 11),
    legend.position = "right"
  ) +
  guides(
    fill = guide_legend(title = "Donations\nLevel"),
    pattern_type = guide_legend(title = "Donations\nLevel"),
    pattern_fill = "none"
  )

print(p4b)
```

### Illegitimate Births (Sequential Palette)

```{r map-infants, fig.height=7, fig.width=8}
p5 <- ggplot(france_data) +
  geom_sf(aes(fill = Infants_rank), color = "black", linewidth = 0.3) +
  scale_fill_cheysson("1891_07", discrete = FALSE,
                      name = "Rank") +
  labs(
    title = "Illegitimate Births",
    subtitle = "Population per illegitimate birth (ranked by department)",
    caption = "Data: André-Michel Guerry (1833)"
  ) +
  theme_cheysson_map() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12),
    legend.position = "right"
  )

print(p5)
```

### Suicides (Different Sequential Palette)

```{r map-suicides, fig.height=7, fig.width=8}
p6 <- ggplot(france_data) +
  geom_sf(aes(fill = Suicides_rank), color = "black", linewidth = 0.3) +
  scale_fill_cheysson("1887_06", discrete = FALSE,
                      name = "Rank") +
  labs(
    title = "Suicides",
    subtitle = "Annual suicides per population (ranked by department)",
    caption = "Data: André-Michel Guerry (1833)"
  ) +
  theme_cheysson_map() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12),
    legend.position = "right"
  )

print(p6)
```

## Small Multiples: Comparing Crime Types

Create a faceted map showing multiple variables at once:

```{r map-faceted, fig.height=8, fig.width=10}
# Prepare data in long format for faceting
library(tidyr)
library(dplyr)

crime_long <- france_data |>
  st_as_sf() |>
  select(Department, Crime_pers_rank, Crime_prop_rank,
         Literacy_rank, Suicides_rank) |>
  pivot_longer(cols = ends_with("_rank"),
               names_to = "Variable",
               values_to = "Rank") |>
  mutate(Variable = recode(Variable,
                          "Crime_pers_rank" = "Crimes Against Persons",
                          "Crime_prop_rank" = "Property Crimes",
                          "Literacy_rank" = "Literacy Rate",
                          "Suicides_rank" = "Suicides"))

p7 <- ggplot(crime_long) +
  geom_sf(aes(fill = Rank), color = "grey30", linewidth = 0.2) +
  scale_fill_cheysson("1895_04", discrete = FALSE,
                      name = "Rank") +
  facet_wrap(~ Variable, ncol = 2) +
  labs(
    title = "Social Statistics of France, 1830s",
    subtitle = "Four measures of moral statistics (ranked by department)",
    caption = "Data: André-Michel Guerry (1833)"
  ) +
  theme_cheysson_map() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12),
    strip.background = element_rect(fill = "#edd493", color = "black"),
    strip.text = element_text(size = 10, face = "bold"),
    legend.position = "bottom",
    legend.key.width = unit(2, "cm")
  )

print(p7)
```

## Regional Patterns

Let's also examine regional patterns using discrete categories:

```{r map-by-region, fig.height=7, fig.width=8}
# Map showing regions
# Note: After merge, Region column may be duplicated as Region.x or Region.y
# We'll use the spatial data version (Region.x) or check which exists
region_col <- if("Region" %in% names(france_data)) {
  "Region"
} else if("Region.x" %in% names(france_data)) {
  "Region.x"
} else {
  "Region.y"
}

p8 <- ggplot(france_data) +
  geom_sf(aes(fill = .data[[region_col]]), color = "black", linewidth = 0.4) +
  scale_fill_cheysson("category",
                      name = "Region") +
  labs(
    title = "Regions of France",
    subtitle = "Administrative divisions circa 1830",
    caption = "Source: Guerry package"
  ) +
  theme_cheysson_map() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 12),
    legend.position = "right"
  )

print(p8)
```

### Regions with Patterns: Classic Cheysson Cartography

One of Cheysson's most distinctive techniques was using varied hatching patterns to distinguish regions:

```{r map-regions-pattern, fig.height=7, fig.width=8}
# Regions with distinctive patterns - very characteristic of Cheysson
p8b <- ggplot(france_data) +
  geom_sf_pattern(
    aes(fill = .data[[region_col]],
        pattern_type = .data[[region_col]],
        pattern_fill = .data[[region_col]]),
    pattern = "stripe",
    pattern_density = 0.3,
    pattern_spacing = 0.02,
    color = "black",
    linewidth = 0.5
  ) +
  scale_fill_cheysson_pattern("category") +
  scale_pattern_fill_cheysson("category") +
  scale_pattern_type_cheysson("category") +
  labs(
    title = "Regions of France with Cheysson Patterns",
    subtitle = "Distinctive hatching patterns for each region - authentic Albums style",
    caption = "Source: Guerry package"
  ) +
  theme_cheysson_map() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 11),
    legend.position = "right"
  ) +
  guides(
    fill = guide_legend(title = "Region"),
    pattern_type = guide_legend(title = "Region"),
    pattern_fill = "none"
  )

print(p8b)
```

## Bivariate Comparison

Compare two variables using different visual encodings:

```{r map-bivariate, fig.height=7, fig.width=9}
# Create categories for both variables
france_data$Crime_cat <- cut(france_data$Crime_pers_rank,
                             breaks = 3,
                             labels = c("Low", "Medium", "High"))

france_data$Lit_cat <- cut(france_data$Literacy_rank,
                           breaks = 3,
                           labels = c("Low", "Medium", "High"))

# Create bivariate category
france_data$Bivariate <- paste0(france_data$Crime_cat, "\n",
                                france_data$Lit_cat, " Literacy")

# Plot
p9 <- ggplot(france_data) +
  geom_sf(aes(fill = Crime_pers_rank), color = "black", linewidth = 0.5) +
  scale_fill_cheysson("1895_04", discrete = FALSE, name = "Crime\nRank") +
  # Add point symbols sized by literacy
  geom_sf_text(aes(label = ifelse(Literacy_rank > 70, "H",
                                  ifelse(Literacy_rank < 25, "L", ""))),
               size = 3, fontface = "bold") +
  labs(
    title = "Crime vs. Literacy",
    subtitle = "Crime Against Persons (color) and Literacy (H=High, L=Low)",
    caption = "Data: André-Michel Guerry (1833)"
  ) +
  theme_cheysson_map() +
  theme(
    plot.title = element_text(size = 16, face = "bold"),
    plot.subtitle = element_text(size = 11)
  )

print(p9)
```

## Historical Context

### About Guerry's Data

André-Michel Guerry (1802-1866) was a French lawyer and statistician who pioneered the use of statistical graphics and thematic maps. His 1833 *Essai sur la statistique morale de la France* was one of the first works to:

- Use choropleth maps to visualize social data
- Examine geographical patterns in crime, literacy, and social indicators
- Apply statistical methods to moral and social questions

### About the Variables

- **Crime_pers**: Crimes against persons (per capita)
- **Crime_prop**: Crimes against property (per capita)
- **Literacy**: Percent of military conscripts who can read and write
- **Donations**: Donations to the poor (per capita)
- **Infants**: Population per illegitimate birth
- **Suicides**: Annual suicides (per capita)

### The Connection to Cheysson

Émile Cheysson (1836-1910), working 40-50 years after Guerry, brought similar statistical visualization techniques to new heights in the *Albums de Statistique Graphique*. By combining Guerry's data with Cheysson's visual style, we honor both pioneers of data visualization.

## Available Palettes

The ggCheysson package includes multiple palettes suitable for choropleth maps:

```{r show-palettes}
# Sequential palettes (good for continuous rankings)
list_cheysson_pals("sequential")

# Grouped palettes (good for categories)
list_cheysson_pals("grouped")

# Category palettes (good for discrete regions)
list_cheysson_pals("category")
```

**Note**: When using `discrete = FALSE`, even category palettes can create smooth color gradients for continuous data. The package includes:
- 7 Sequential palettes (varying colors: 1-3)
- 2 Diverging palettes (2-3 colors)
- 5 Grouped palettes (2-5 colors)
- 6 Category palettes (3-7 colors)

## Summary

This vignette demonstrated:

- Converting SpatialPolygonsDataFrame to sf objects for ggplot2
- Joining spatial and tabular data
- Creating choropleth maps with various Cheysson color palettes
- **Using Cheysson hatching patterns combined with colors** - a signature feature of the Albums
- Applying `geom_sf_pattern()` with pattern scales for authentic Cheysson cartography
- Using `theme_cheysson_map()` for cartographic styling
- Displaying multiple maps in faceted layouts
- Combining historical data with historical cartographic styles

### Key Cheysson Techniques Illustrated

The pattern-enhanced maps (literacy, donations, and regions) showcase Cheysson's most distinctive cartographic innovation: **combining colors with hatching patterns**. This dual encoding:

- Enhances visual distinction between categories
- Creates rich, textured maps characteristic of 19th century statistical graphics
- Improves readability and aesthetic appeal
- Provides redundant encoding (both color and pattern) for better accessibility

These techniques defined the visual language of the *Albums de Statistique Graphique* and influenced statistical cartography for decades.

The combination of Guerry's groundbreaking statistical data with Cheysson's elegant visual style creates a fitting tribute to the pioneers of statistical graphics and thematic cartography.

## References

- Guerry, A.-M. (1833). *Essai sur la statistique morale de la France*. Paris: Crochard.
- Friendly, M. (2007). A.-M. Guerry's *Moral Statistics of France*: Challenges for Multivariable Spatial Analysis. *Statistical Science*, **22**(3), 368-399.
- Friendly, M. (2008). The Golden Age of Statistical Graphics. *Statistical Science*, **23**(4), 502-535.

```{r cleanup, include=FALSE}
# Clean up
if (exists("fonts_available") && fonts_available) {
  showtext::showtext_auto(FALSE)
}
```
