Taux de chômage localisés par zone d’emploi - chomage-zone-2003-2020

Données - INSEE

Taux de chômage localisés (au sens du BIT, en %) de 302 zones d’emploi (zonage 2020 ; hors Guyane et Mayotte), de 2003 à 2020. Les médianes et centiles ci-dessous sont des statistiques sur les zones, non pondérées par la population active et calculées sur les 287 zones suivies sur toute la période (les zones des DOM n’apparaissent que plus tard). La feuille « parties régionales » détaille en outre les zones interrégionales par région (28 parties).

Dispersion du chômage entre zones d’emploi

Code
disp <- ze |>
  filter(zone_code %in% zones_eq) |>
  group_by(date) |>
  summarise(p10 = quantile(taux, .1), q1 = quantile(taux, .25), med = median(taux),
            q3 = quantile(taux, .75), p90 = quantile(taux, .9), .groups = "drop")
ze |>
  ggplot(aes(x = date, y = taux, group = zone_code)) +
  geom_line(color = "grey80", linewidth = 0.2) +
  geom_ribbon(data = disp, aes(x = date, ymin = p10, ymax = p90), inherit.aes = FALSE, fill = bleu, alpha = 0.15) +
  geom_ribbon(data = disp, aes(x = date, ymin = q1, ymax = q3), inherit.aes = FALSE, fill = bleu, alpha = 0.25) +
  geom_line(data = disp, aes(x = date, y = med), inherit.aes = FALSE, color = bleu, linewidth = 1.3) +
  scale_x_date(date_breaks = "2 years", date_labels = "%Y") +
  theme_ze() +
  labs(x = NULL, y = "%", title = "Une médiane qui suit le cycle, un éventail qui reste large",
       subtitle = sprintf("trait gras : médiane (%.1f %% en %s) ; bandes : écart interquartile et déciles 1-9", disp$med[disp$date == dmax], fmt_per(dmax)))

Code
disp |>
  mutate(ecart = p90 - p10) |>
  ggplot(aes(x = date, y = ecart)) +
  geom_line(color = rose, linewidth = 1.2) +
  geom_point(color = rose, size = 1.5) +
  scale_x_date(date_breaks = "2 years", date_labels = "%Y") +
  theme_ze() +
  labs(x = NULL, y = "points de %", title = "Écart entre le 9e et le 1er décile de taux de chômage",
       subtitle = "zones d'emploi, non pondéré")

Zones d’emploi les plus et les moins touchées

Code
dern <- ze |> filter(date == dmax)
sel <- bind_rows(dern |> slice_max(taux, n = 15, with_ties = FALSE) |> mutate(groupe = "Les plus élevés"),
                 dern |> slice_min(taux, n = 15, with_ties = FALSE) |> mutate(groupe = "Les plus faibles")) |>
  mutate(lab = paste0(zone, " (", str_to_title(region), ")") |> str_trunc(46))
sel |>
  mutate(lab = fct_reorder(lab, taux)) |>
  ggplot(aes(x = taux, y = lab, fill = groupe)) +
  geom_col(show.legend = FALSE) +
  geom_text(aes(label = sprintf("%.1f", taux)), hjust = -0.2, size = 3) +
  facet_wrap(~ groupe, scales = "free_y", ncol = 1) +
  scale_fill_manual(values = c("Les plus élevés" = rose, "Les plus faibles" = vert)) +
  scale_x_continuous(expand = expansion(mult = c(0, 0.12))) +
  theme_ze() +
  labs(x = "%", y = NULL, title = paste("Taux de chômage par zone d'emploi,", fmt_per(dmax)),
       subtitle = "15 zones aux taux les plus élevés et les plus faibles")

Grandes agglomérations

Code
villes <- c("Paris", "Lyon", "Marseille", "Lille", "Toulouse", "Bordeaux", "Nantes", "Strasbourg", "Perpignan", "Saint-Nazaire")
ze |>
  filter(zone %in% villes) |>
  mutate(zone = factor(zone, levels = villes)) |>
  ggplot(aes(x = date, y = taux, color = zone)) +
  geom_line(data = disp, aes(x = date, y = med), inherit.aes = FALSE, color = "grey60", linewidth = 1, linetype = "dashed") +
  geom_line(linewidth = 1) +
  geom_text_repel(data = ~ filter(.x, date == dmax), aes(label = zone), size = 3, direction = "y",
                  hjust = 0, nudge_x = 200, segment.size = 0.2, show.legend = FALSE) +
  scale_x_date(date_breaks = "2 years", date_labels = "%Y", expand = expansion(mult = c(0.02, 0.15))) +
  scale_color_manual(values = c("#1B3F8B", "#E8737A", "#4ABFB0", "#F2B134", "#7B4F9D", "#2E8B57", "#C0392B", "#16A5C9", "#8C6D31", "#555555")) +
  theme_ze() + theme(legend.position = "none") +
  labs(x = NULL, y = "%", title = "Chômage dans dix grandes zones d'emploi",
       subtitle = "tirets gris : médiane des zones d'emploi")

Évolution depuis 2019

Code
evo <- ze |>
  filter(date %in% c(dref, dmax)) |>
  select(zone_code, zone, region, date, taux) |>
  pivot_wider(names_from = date, values_from = taux, names_prefix = "d") |>
  rename(avant = 4, apres = 5) |>
  mutate(var = apres - avant)
lab <- bind_rows(slice_max(evo, var, n = 6, with_ties = FALSE), slice_min(evo, var, n = 6, with_ties = FALSE))
evo |>
  ggplot(aes(x = avant, y = apres)) +
  geom_abline(slope = 1, intercept = 0, color = "grey50") +
  geom_point(aes(color = var), size = 2, alpha = 0.8) +
  geom_text_repel(data = lab, aes(label = zone), size = 3, max.overlaps = 30, segment.size = 0.2) +
  scale_color_gradient2(low = vert, mid = "grey70", high = rose, midpoint = 0, name = "Variation (pts)") +
  theme_ze() +
  labs(x = paste("Taux de chômage,", fmt_per(dref)), y = paste("Taux de chômage,", fmt_per(dmax)),
       title = paste("Taux de chômage par zone d'emploi :", fmt_per(dref), "contre", fmt_per(dmax)),
       subtitle = sprintf("sous la diagonale : baisse ; %d zones sur %d ont un taux plus bas qu'en %s",
                          sum(evo$var < 0, na.rm = TRUE), sum(!is.na(evo$var)), fmt_per(dref)))

Médiane par région

Code
reg <- ze |>
  filter(region != "INTERRÉGIONAL") |>
  group_by(region, date) |>
  summarise(med = median(taux), .groups = "drop") |>
  mutate(region = str_to_title(region))
reg |>
  ggplot(aes(x = date, y = med, color = region)) +
  geom_line(linewidth = 0.9) +
  geom_text_repel(data = ~ filter(.x, date == dmax), aes(label = region), size = 3, direction = "y",
                  hjust = 0, nudge_x = 200, segment.size = 0.2) +
  scale_x_date(date_breaks = "2 years", date_labels = "%Y", expand = expansion(mult = c(0.02, 0.3))) +
  scale_color_viridis_d(option = "turbo") +
  theme_ze() + theme(legend.position = "none") +
  labs(x = NULL, y = "%", title = "Médiane des taux de chômage des zones d'emploi, par région",
       subtitle = "médiane non pondérée ; zones interrégionales exclues")

Heatmap

Code
ze |>
  filter(region != "INTERRÉGIONAL") |>
  group_by(region, date) |>
  summarise(med = median(taux), .groups = "drop") |>
  mutate(region = fct_reorder(str_to_title(region), med, .fun = function(x) x[length(x)])) |>
  ggplot(aes(x = date, y = region, fill = med)) +
  geom_tile() +
  scale_fill_viridis_c(option = "magma", direction = -1, name = "%") +
  scale_x_date(date_breaks = "2 years", date_labels = "%Y", expand = c(0, 0)) +
  theme_ze() + theme(legend.position = "right") +
  labs(x = NULL, y = NULL, title = "Chômage régional (médiane des zones)", subtitle = "classement selon le dernier point")

Données

Code
ze |> filter(date == dmax) |> arrange(desc(taux)) |>
  select(zone_code, zone, region, taux) |>
  print_table_conditional()