Impôt sur le revenu par commune (IRCOM), revenus 2024

Données - DGFIP

Code
source(here::here("_rinit.R"))
invisible(Sys.setlocale("LC_TIME", "fr_FR.UTF-8"))
# cd ~/iCloud/website/data/dgfip; /usr/local/bin/R -e 'quarto::quarto_render("ir-communes.qmd")'
# cd ~/iCloud/website/data; sh _status/run_all_silent.sh --only dgfip

knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE,
                       fig.width = 9, fig.height = 5.5, dpi = 150)
source(here::here("data", "dgfip", "_cartes.R"))

ir_communes_path <- here::here("data", "dgfip", "ir-communes.parquet")
irc <- arrow::read_parquet(ir_communes_path)
fr <- scales::label_number(big.mark = " ", decimal.mark = ",")

theme_dgfip <- theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold"),
        plot.subtitle = element_text(colour = "grey35"),
        panel.grid.minor = element_blank())

Source : DGFIP, IRCOM, impôt sur le revenu des revenus de 2024 (déclarés en 2025), par commune et par tranche de revenu fiscal de référence (RFR). Le détail par tranche n’existe que pour les communes les plus peuplées ; la ligne Total existe partout. Les montants sont en milliers d’euros ; n.c. (non communiqué) = secret statistique. Paris est ventilé par arrondissement. Fonds de carte : IGN GEOFLA 2016.

Code
totaux <- irc |>
  dplyr::filter(tranche_rfr == "Total") |>
  dplyr::mutate(rfr_moyen = 1000 * rfr / nb_foyers,
                impot_moyen = 1000 * impot_net / nb_foyers,
                part_imposes = nb_foyers_imposes / nb_foyers)

Région parisienne

Code
idf <- communes_sf(IDF, paris_unique = FALSE)
idf_dep <- departements_sf(idf)
idf_totaux <- idf |> dplyr::left_join(totaux, by = "code_insee")

Revenu fiscal de référence moyen par foyer fiscal

Code
carte(idf_totaux, "rfr_moyen",
      "Revenu fiscal de référence moyen par foyer fiscal",
      "Île-de-France, revenus 2024, euros par foyer", "€ par foyer", idf_dep,
      limites = c(20000, 80000), labels = fr)

Part des foyers fiscaux imposés

Code
carte(idf_totaux, "part_imposes",
      "Part des foyers fiscaux imposés",
      "Île-de-France, revenus 2024", "Part imposée", idf_dep,
      palette = "magma", direction = -1, labels = scales::label_percent(accuracy = 1))

Impôt net moyen par foyer fiscal

Code
carte(idf_totaux, "impot_moyen",
      "Impôt sur le revenu net moyen par foyer fiscal",
      "Île-de-France, revenus 2024, euros par foyer (tous foyers, imposés ou non)", "€ par foyer", idf_dep,
      palette = "plasma", direction = -1, limites = c(0, 12000), labels = fr)

Zoom sur Paris et la petite couronne

Code
pc0 <- communes_sf(c("75", "92", "93", "94"), paris_unique = FALSE)
pc <- pc0 |> dplyr::left_join(dplyr::select(totaux, code_insee, rfr_moyen), by = "code_insee")
carte(pc, "rfr_moyen",
      "Revenu fiscal de référence moyen par foyer fiscal : Paris et petite couronne",
      "Paris par arrondissement, revenus 2024", "€ par foyer", departements_sf(pc0),
      limites = c(20000, 120000), labels = fr)

Communes les plus et les moins aisées (Île-de-France, plus de 2 000 foyers)

Code
cl <- totaux |>
  dplyr::filter(substr(code_insee, 1, 2) %in% IDF, nb_foyers >= 2000)
dplyr::bind_rows(
  cl |> dplyr::slice_max(rfr_moyen, n = 15) |> dplyr::mutate(groupe = "15 communes les plus aisées"),
  cl |> dplyr::slice_min(rfr_moyen, n = 15) |> dplyr::mutate(groupe = "15 communes les moins aisées")) |>
  dplyr::mutate(libelle = forcats::fct_reorder(libelle, rfr_moyen)) |>
  ggplot(aes(libelle, rfr_moyen, fill = groupe)) +
  geom_col() + coord_flip() + facet_wrap(~groupe, scales = "free_y", ncol = 1) +
  scale_y_continuous(labels = fr) +
  scale_fill_manual(values = c("#b2182b", "#2166ac")) +
  labs(title = "Revenu fiscal de référence moyen par foyer", x = NULL, y = "€ par foyer") +
  theme_dgfip + theme(legend.position = "none")

RFR moyen et part de foyers imposés

Code
cl |>
  dplyr::mutate(dep = substr(code_insee, 1, 2)) |>
  ggplot(aes(rfr_moyen, part_imposes, colour = dep, size = nb_foyers)) +
  geom_point(alpha = 0.6) +
  scale_x_continuous(labels = fr) + scale_y_continuous(labels = scales::label_percent()) +
  scale_size_area(max_size = 6, guide = "none") + scale_colour_viridis_d(name = "Dép.") +
  labs(title = "Revenu moyen et part de foyers imposés, communes d'Île-de-France",
       subtitle = "Communes de plus de 2 000 foyers ; taille = nombre de foyers",
       x = "RFR moyen par foyer (€)", y = "Part de foyers imposés") + theme_dgfip

Répartition par tranche de revenu

Code
niveaux <- c("0 à 10 000", "10 001 à 12 000", "12 001 à 15 000", "15 001 à 20 000",
             "20 001 à 30 000", "30 001 à 50 000", "50 001 à 100 000", "+ de 100 000")
villes <- c("Paris" = "^75", "Neuilly-sur-Seine" = "^92051$", "Boulogne-Billancourt" = "^92012$",
            "Versailles" = "^78646$", "Nanterre" = "^92050$", "Montreuil" = "^93048$",
            "Saint-Denis" = "^93066$", "Clichy-sous-Bois" = "^93014$")
purrr::imap_dfr(villes, \(re, nom) {
  irc |>
    dplyr::filter(tranche_rfr != "Total", grepl(re, code_insee)) |>
    dplyr::group_by(tranche_rfr) |>
    dplyr::summarise(nb_foyers = sum(nb_foyers, na.rm = TRUE), .groups = "drop") |>
    dplyr::mutate(part = nb_foyers / sum(nb_foyers), ville = nom)
}) |>
  dplyr::mutate(tranche_rfr = factor(tranche_rfr, levels = niveaux),
                ville = factor(ville, levels = names(villes))) |>
  ggplot(aes(tranche_rfr, part, fill = tranche_rfr)) +
  geom_col() + facet_wrap(~ville, ncol = 4) +
  scale_y_continuous(labels = scales::label_percent(accuracy = 1)) +
  scale_fill_viridis_d(guide = "none") +
  labs(title = "Répartition des foyers fiscaux par tranche de revenu fiscal de référence",
       x = NULL, y = "Part des foyers") +
  theme_dgfip + theme(axis.text.x = element_text(angle = 60, hjust = 1, size = 7))

France entière

Code
fr_sf <- communes_sf(depts = NULL, paris_unique = FALSE, simplifier = 400)
fr_sf <- fr_sf |> dplyr::filter(!dep %in% c("2A", "2B") | TRUE) |>
  dplyr::left_join(totaux, by = "code_insee")

RFR moyen par foyer fiscal, communes de France métropolitaine

Code
carte(fr_sf, "rfr_moyen",
      "Revenu fiscal de référence moyen par foyer fiscal",
      "Communes, revenus 2024 ; les communes fusionnées depuis 2016 restent en gris",
      "€ par foyer", limites = c(15000, 50000), labels = fr)

Les 20 communes de plus de 5 000 foyers au revenu moyen le plus élevé

Code
totaux |>
  dplyr::filter(nb_foyers >= 5000) |>
  dplyr::slice_max(rfr_moyen, n = 20) |>
  dplyr::mutate(libelle = forcats::fct_reorder(paste0(libelle, " (", code_insee, ")"), rfr_moyen)) |>
  ggplot(aes(libelle, rfr_moyen)) +
  geom_col(fill = "#b2182b") + coord_flip() +
  scale_y_continuous(labels = fr) +
  labs(x = NULL, y = "RFR moyen par foyer (€)") + theme_dgfip