Last data update: 26 oct. 2026, 20:00
Last compile: 26 oct. 2026, 20:02
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).
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)))
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é")
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")
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")
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)))
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")
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")
ze |> filter(date == dmax) |> arrange(desc(taux)) |>
select(zone_code, zone, region, taux) |>
print_table_conditional()