Les arbres de Paris — inventaire

Données - Ville de Paris

Code
source(here::here("_rinit.R"))
source(here::here("data", "paris", "_paris.R"))   # wkb2sfc(), paris_basemap(), arrondissements_sf()
invisible(Sys.setlocale("LC_TIME", "fr_FR.UTF-8"))
# cd ~/iCloud/website/data/paris; /usr/local/bin/R -e 'quarto::quarto_render("les-arbres.qmd")'

knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE,
                      fig.width = 8, fig.height = 5, dpi = 150)

arbres_path <- here::here("data", "paris", "les-arbres.parquet")
arbres <- arrow::read_parquet(arbres_path)

# geo_point_2d (WKB) -> lon / lat
xy <- sf::st_coordinates(wkb2sfc(arbres$geo_point_2d))

arbres <- arbres |>
  dplyr::mutate(
    lon = xy[, 1], lat = xy[, 2],
    ar  = suppressWarnings(as.integer(stringr::str_extract(arrondissement, "[0-9]+"))),
    ar  = dplyr::if_else(stringr::str_detect(arrondissement, "PARIS"), ar, NA_integer_),
    stade = dplyr::recode(stadedeveloppement,
                          "Jeune (arbre)" = "Jeune",
                          "Jeune (arbre)Adulte" = "Jeune à adulte",
                          .missing = "Non renseigné"),
    stade = factor(stade, levels = c("Jeune", "Jeune à adulte", "Adulte", "Mature", "Non renseigné"))
  )

n_tot <- nrow(arbres)
arr_sf <- arrondissements_sf()

theme_carte <- theme_void(base_size = 12) +
  theme(plot.title = element_text(face = "bold"),
        plot.subtitle = element_text(colour = "grey35"),
        plot.margin = margin(5, 12, 5, 5))
theme_barres <- theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold"),
        plot.subtitle = element_text(colour = "grey35"),
        panel.grid.major.y = element_blank())

Inventaire géolocalisé des 219 972 arbres gérés par la Ville de Paris : arbres d’alignement (le long des voies), arbres des jardins, des cimetières, des écoles, des équipements sportifs et des bois. Pour chaque arbre : genre et espèce, circonférence, hauteur, stade de développement, domanialité, adresse. Les arbres des forêts denses des bois n’y sont pas tous recensés individuellement.

C’est l’inventaire de référence derrière les jeux arbres plantés et arbres abattus pour raisons sanitaires.

Code
arbres |>
  dplyr::slice_sample(n = 12) |>
  dplyr::transmute(
    Arrondissement = arrondissement, Adresse = adresse, `Domanialité` = domanialite,
    Essence = libellefrancais, Genre = genre, `Espèce` = espece,
    `Circonf. (cm)` = circonferenceencm, `Hauteur (m)` = hauteurenm,
    Stade = as.character(stade)
  ) |>
  gt::gt() |>
  gt::sub_missing(missing_text = "—") |>
  gt::tab_header(title = "12 arbres tirés au hasard") |>
  gt::tab_options(table.width = "100%")
12 arbres tirés au hasard
Arrondissement Adresse Domanialité Essence Genre Espèce Circonf. (cm) Hauteur (m) Stade
PARIS 16E ARRDT ECOLE ELEMENTAIRE / 51 RUE MICHEL ANGE DASCO Erable Acer campestre 25 5 Jeune
PARIS 4E ARRDT QUAI HENRI IV Alignement Platane Platanus x hispanica 55 10 Jeune à adulte
PARIS 15E ARRDT JARDIN MARGUERITE BOUCICAUT / 7 ALLEE ISADORA DUNCAN Jardin Gainier Cercis canadensis 15 2 Jeune
PARIS 10E ARRDT QUAI DE VALMY Alignement Peuplier Populus x canadensis 218 22 Mature
PARIS 17E ARRDT TALUS N°16-07 PERIPHERIQUE Robinier Robinia pseudoacacia 40 7 Jeune
PARIS 20E ARRDT PLACE DE LA PORTE DE BAGNOLET Alignement Platane Platanus x hispanica 90 13 Jeune à adulte
PARIS 4E ARRDT BOULEVARD BEAUMARCHAIS Alignement Platane Platanus x hispanica 90 8 Jeune à adulte
PARIS 18E ARRDT SQUARE ALAIN BASHUNG / 16 RUE DE JESSAINT Jardin Merisier Prunus avium 95 13 Adulte
SEINE-SAINT-DENIS CIMETIERE DE PANTIN / AVENUE DES NEGUNDOS / DIV 115 CIMETIERE Tilleul Tilia cordata 30 4 Jeune
PARIS 17E ARRDT PARC CLICHY BATIGNOLLES MARTIN LUTHER KING / 147 RUE CARDINET Jardin Tilleul Tilia x europaea 78 7 Jeune à adulte
SEINE-SAINT-DENIS CIMETIERE DE PANTIN / AVENUE PRINCIPALE / DIV 97 CIMETIERE Marronnier Aesculus hippocastanum 190 20 Adulte
HAUTS-DE-SEINE CIMETIERE DE BAGNEUX / AVENUE DE MONTROUGE / DIV 0 CIMETIERE Tilleul Tilia x euchlora 160 15 Adulte

Où sont les arbres

Code
ggplot(arbres, aes(lon, lat)) +
  geom_hex(bins = 90) +
  geom_sf(data = arr_sf, fill = NA, colour = "white", linewidth = 0.2, inherit.aes = FALSE) +
  scale_fill_viridis_c(option = "mako", direction = -1, trans = "log10",
                       name = "Arbres par\nalvéole", labels = scales::label_number()) +
  coord_sf(xlim = c(2.222, 2.470), ylim = c(48.812, 48.914), expand = FALSE) +
  labs(title = paste0("Densité de l'inventaire — ", format(n_tot, big.mark = " "), " arbres"),
       subtitle = "Alvéoles hexagonales ; les deux bois et les grands cimetières ressortent") +
  theme_carte

Code
cnt_ar <- arbres |>
  dplyr::filter(!is.na(ar)) |>
  dplyr::count(ar, name = "n")

arr_sf |>
  dplyr::left_join(cnt_ar, by = c("c_ar" = "ar")) |>
  ggplot() +
  geom_sf(aes(fill = n), colour = "white", linewidth = 0.2) +
  scale_fill_viridis_c(option = "mako", direction = -1, na.value = "grey92",
                       labels = scales::label_number(big.mark = " "), name = "Arbres") +
  labs(title = "Arbres inventoriés par arrondissement",
       subtitle = "Hors bois de Boulogne et de Vincennes (comptés à part)") +
  theme_carte

Les essences

Code
arbres |>
  dplyr::filter(!is.na(libellefrancais), libellefrancais != "") |>
  dplyr::count(libellefrancais, sort = TRUE) |>
  head(15) |>
  dplyr::mutate(libellefrancais = forcats::fct_reorder(libellefrancais, n)) |>
  ggplot(aes(n, libellefrancais)) +
  geom_col(fill = "#2f6f4f", width = 0.7) +
  geom_text(aes(label = format(n, big.mark = " ")), hjust = -0.15, size = 3) +
  scale_x_continuous(labels = scales::label_number(big.mark = " "),
                     expand = expansion(mult = c(0, 0.12))) +
  labs(title = "15 essences les plus fréquentes",
       subtitle = "Platane, marronnier, tilleul et érable dominent le paysage arboré parisien",
       x = NULL, y = NULL) +
  theme_barres

Code
g <- sort(table(arbres$genre), decreasing = TRUE)
cat(sprintf(
  "\nLe patrimoine est **peu diversifié** : les 5 genres les plus courants (%s) représentent **%s** des arbres. Cette monoculture partielle explique la vulnérabilité aux maladies visible dans le jeu [arbres abattus](arbres-abattus-pour-raison-sanitaires-et-essence-de-remplacement.html) (chancre du platane, mineuse du marronnier…).\n",
  paste(names(g)[1:5], collapse = ", "),
  scales::percent(sum(g[1:5]) / sum(g), 1)))

Le patrimoine est peu diversifié : les 5 genres les plus courants (Platanus, Aesculus, Tilia, Acer, Styphnolobium) représentent 56% des arbres. Cette monoculture partielle explique la vulnérabilité aux maladies visible dans le jeu arbres abattus (chancre du platane, mineuse du marronnier…).

La place du platane

Code
arbres |>
  dplyr::filter(!is.na(ar)) |>
  dplyr::group_by(ar) |>
  dplyr::summarise(part_platane = mean(genre == "Platanus", na.rm = TRUE), .groups = "drop") |>
  dplyr::right_join(arr_sf, by = c("ar" = "c_ar")) |>
  sf::st_as_sf() |>
  ggplot() +
  geom_sf(aes(fill = part_platane), colour = "white", linewidth = 0.2) +
  scale_fill_viridis_c(option = "rocket", direction = -1, labels = scales::percent,
                       na.value = "grey92", name = "Part du\nplatane") +
  labs(title = "Part des platanes dans l'inventaire, par arrondissement",
       subtitle = "Jusqu'à ~46 % dans le 7ᵉ (esplanade des Invalides, Champ-de-Mars)") +
  theme_carte

Par type d’espace

Code
arbres |>
  dplyr::mutate(domanialite = dplyr::recode(domanialite,
    DASCO = "Écoles (DASCO)", DJS = "Sport (DJS)", DFPE = "Petite enfance (DFPE)",
    DAC = "Culture (DAC)", PERIPHERIQUE = "Boulevard périphérique")) |>
  dplyr::count(domanialite, sort = TRUE) |>
  dplyr::mutate(domanialite = forcats::fct_reorder(domanialite, n)) |>
  ggplot(aes(n, domanialite)) +
  geom_col(fill = "#3b6f8a", width = 0.7) +
  geom_text(aes(label = format(n, big.mark = " ")), hjust = -0.15, size = 3) +
  scale_x_continuous(labels = scales::label_number(big.mark = " "),
                     expand = expansion(mult = c(0, 0.12))) +
  labs(title = "Arbres par domanialité",
       subtitle = "La moitié sont des arbres d'alignement le long des voies",
       x = NULL, y = NULL) +
  theme_barres

Âge et gabarit

Code
arbres |>
  dplyr::count(stade) |>
  ggplot(aes(n, forcats::fct_rev(stade))) +
  geom_col(fill = "#7a5a2b", width = 0.7) +
  geom_text(aes(label = format(n, big.mark = " ")), hjust = -0.15, size = 3) +
  scale_x_continuous(labels = scales::label_number(big.mark = " "),
                     expand = expansion(mult = c(0, 0.12))) +
  labs(title = "Stade de développement", x = NULL, y = NULL) +
  theme_barres

Code
arbres |>
  dplyr::filter(circonferenceencm > 0, circonferenceencm < 600,
                hauteurenm > 0, hauteurenm < 45) |>
  ggplot(aes(circonferenceencm, hauteurenm)) +
  geom_hex(bins = 45) +
  scale_fill_viridis_c(option = "mako", direction = -1, trans = "log10", name = "Arbres") +
  labs(title = "Circonférence et hauteur",
       subtitle = "Circonférence du tronc à 1 m du sol · valeurs nulles (non mesurées) exclues",
       x = "Circonférence (cm)", y = "Hauteur (m)") +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold"),
        plot.subtitle = element_text(colour = "grey35"))

Arbres remarquables

Code
rem <- dplyr::filter(arbres, remarquable == "OUI")

ggplot() +
  geom_sf(data = arr_sf, fill = "grey96", colour = "white") +
  geom_point(data = rem, aes(lon, lat), colour = "#c0392b", size = 1.6, alpha = 0.8) +
  coord_sf(xlim = c(2.222, 2.470), ylim = c(48.812, 48.914), expand = FALSE) +
  labs(title = paste0(nrow(rem), " arbres classés « remarquables »"),
       subtitle = "Âge, dimensions, rareté de l'espèce, histoire ou esthétique") +
  theme_carte

Code
rem |>
  dplyr::transmute(
    Arrondissement = arrondissement, Adresse = adresse,
    Essence = libellefrancais, Genre = genre, `Espèce` = espece,
    `Circonf. (cm)` = circonferenceencm, `Hauteur (m)` = hauteurenm
  ) |>
  dplyr::arrange(dplyr::desc(`Circonf. (cm)`)) |>
  DT::datatable(rownames = FALSE, filter = "top",
                options = list(pageLength = 10, order = list(list(5, "desc"))))

Source & données

Code
tibble::tibble(
  ` ` = c("Jeu de données", "Producteur", "Licence", "Fichier", "Mise à jour", "Observations"),
  `  ` = c(
    "[Les arbres](https://opendata.paris.fr/explore/dataset/les-arbres/)",
    "Direction des Espaces Verts et de l'Environnement (DEVE) — Ville de Paris",
    "Open Database License (ODbL)",
    sprintf("`data/paris/les-arbres.parquet` (%s Mo) + `arrondissements.parquet`",
            round(file.size(arbres_path) / 1024^2, 1)),
    format(as.Date(file.mtime(arbres_path)), "%d %B %Y"),
    sprintf("%s arbres géolocalisés", format(n_tot, big.mark = " "))
  )
) |>
  gt::gt() |> gt::fmt_markdown(columns = `  `) |>
  gt::tab_options(table.width = "100%", column_labels.hidden = TRUE)
Jeu de données Les arbres
Producteur Direction des Espaces Verts et de l’Environnement (DEVE) — Ville de Paris
Licence Open Database License (ODbL)
Fichier data/paris/les-arbres.parquet (6.3 Mo) + arrondissements.parquet
Mise à jour 20 septembre 2026
Observations 219 972 arbres géolocalisés