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("chantiers-perturbants.qmd")'
knitr:: opts_chunk$ set (echo = TRUE , message = FALSE , warning = FALSE ,
fig.width = 8 , fig.height = 5 , dpi = 150 )
ch_path <- here:: here ("data" , "paris" , "chantiers-perturbants.parquet" )
chantiers <- arrow:: read_parquet (ch_path) |>
dplyr:: mutate (ar = suppressWarnings (as.integer (substr (cp_arrondissement, 4 , 5 ))))
n_tot <- nrow (chantiers)
arr_sf <- arrondissements_sf ()
pts_sf <- chantiers |>
dplyr:: filter (lengths (geo_point_2d) > 0 ) |> # 1 chantier sans localisation
dplyr:: mutate (geometry = wkb2sfc (geo_point_2d)) |>
sf:: st_as_sf (crs = 4326 )
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 ())
Les 113 grands chantiers ayant un impact notable sur la circulation — réseaux de chaleur (CPCU/Fraîcheur de Paris), RATP, RTE, SNCF, Eau de Paris… — avec leur emprise, leurs dates prévisionnelles (certaines courent jusqu’en 2031) et leur impact sur la voirie.
Code
chantiers |>
dplyr:: arrange (dplyr:: desc (date_debut)) |>
dplyr:: transmute (Voie = voie, Arrondissement = ar, ` Maître d'ouvrage ` = maitre_ouvrage,
Objet = objet, Début = date_debut, Fin = date_fin,
` Impact circulation ` = impact_circulation) |>
head (8 ) |>
gt:: gt () |>
gt:: sub_missing (missing_text = "—" ) |>
gt:: tab_header (title = "8 chantiers les plus récemment ouverts" ) |>
gt:: tab_options (table.width = "100%" )
Voie
Arrondissement
Maître d'ouvrage
Objet
Début
Fin
Impact circulation
22-24 quai d'Austerlitz
13
—
REHABILITATION_IMMEUBLE
2027-03-29
2027-11-26
RESTREINTE
boulevard du Palais 75004_
4
APIJ
REHABILITATION_IMMEUBLE
2026-11-16
2031-03-31
RESTREINTE
rue de Vaugirard 75006_
6
Sénat
REHABILITATION_IMMEUBLE
2026-11-13
2027-08-31
RESTREINTE
46 rue des Fossés Saint Bernard
5
Fraicheur de Paris
RACCORDEMENT_RESEAU
2026-11-02
2026-11-16
RESTREINTE
avenue de la Porte de Pouchet 75017
17
Ville de Paris
REAMENAGEMENT_VOIRIE
2026-10-26
2026-12-11
RESTREINTE
1 rue des Ecoles
5
Fraicheur de Paris
RACCORDEMENT_RESEAU
2026-10-19
2026-11-02
RESTREINTE
rue de l'université
7
Fraîcheur de Paris
CREATION_RESEAUX
2026-10-19
2026-12-18
RESTREINTE
40 quai des Célestins
4
SAP
ENTRETIEN_RESEAU
2026-09-30
2027-05-14
RESTREINTE
Carte
Code
pal <- leaflet:: colorFactor ("Set1" , domain = chantiers$ impact_circulation)
leaflet:: leaflet (pts_sf, options = leaflet:: leafletOptions (minZoom = 11 )) |>
paris_basemap () |>
leaflet:: addPolygons (data = arr_sf, fill = FALSE , color = "#999" , weight = 1 ) |>
leaflet:: addCircleMarkers (
radius = 6 , stroke = FALSE , fillOpacity = 0.8 ,
fillColor = ~ pal (impact_circulation),
label = ~ sprintf ("%s — %s" , voie, maitre_ouvrage),
popup = ~ sprintf ("<b>%s</b><br>%s<br>%s<br>Du %s au %s<br>Impact : %s" ,
voie, maitre_ouvrage, objet, format (date_debut, "%d/%m/%Y" ),
format (date_fin, "%d/%m/%Y" ), impact_circulation)
) |>
leaflet:: addLegend ("bottomright" , pal = pal, values = ~ impact_circulation,
title = "Impact circulation" , opacity = 0.9 )
Combien de chantiers en même temps
Code
mois_seq <- seq (as.Date (cut (min (chantiers$ date_debut, na.rm = TRUE ), "month" )),
as.Date (cut (max (chantiers$ date_fin, na.rm = TRUE ), "month" )), by = "month" )
n_actifs <- vapply (mois_seq, function (m)
sum (chantiers$ date_debut <= m & chantiers$ date_fin >= m, na.rm = TRUE ), integer (1 ))
tibble:: tibble (mois = mois_seq, n = n_actifs) |>
ggplot (aes (mois, n)) +
geom_area (fill = "#7a5a2b" , alpha = 0.3 ) +
geom_line (colour = "#7a5a2b" , linewidth = 0.9 ) +
scale_x_date (date_labels = "%Y" , date_breaks = "1 year" ) +
labs (title = "Nombre de chantiers perturbants simultanément actifs" ,
subtitle = "D'après les dates de début/fin prévisionnelles renseignées" ,
x = NULL , y = NULL ) +
theme_barres
Qui creuse, et où
Code
chantiers |>
dplyr:: filter (! is.na (maitre_ouvrage)) |>
dplyr:: count (maitre_ouvrage, sort = TRUE ) |>
head (10 ) |>
dplyr:: mutate (maitre_ouvrage = forcats:: fct_reorder (maitre_ouvrage, n)) |>
ggplot (aes (n, maitre_ouvrage)) +
geom_col (fill = "#8a5a2b" , width = 0.6 ) +
geom_text (aes (label = n), hjust = - 0.2 , size = 3 ) +
scale_x_continuous (expand = expansion (mult = c (0 , 0.12 ))) +
labs (title = "Maîtres d'ouvrage les plus présents" ,
subtitle = "Le réseau de chaleur urbain (CPCU / Fraîcheur de Paris) domine" ,
x = NULL , y = NULL ) +
theme_barres
Code
chantiers |>
dplyr:: filter (! is.na (impact_circulation)) |>
dplyr:: count (impact_circulation, sort = TRUE ) |>
dplyr:: mutate (impact_circulation = forcats:: fct_reorder (impact_circulation, n)) |>
ggplot (aes (n, impact_circulation)) +
geom_col (fill = "#c0392b" , width = 0.55 ) +
geom_text (aes (label = n), hjust = - 0.2 , size = 3.2 ) +
scale_x_continuous (expand = expansion (mult = c (0 , 0.12 ))) +
labs (title = "Impact sur la circulation" , x = NULL , y = NULL ) +
theme_barres
Le jeu de données porte aussi des codes niveau_perturbation, statut et typologie — non documentés par la source (pas de légende publiée dans le catalogue ODS), donc non repris ici pour éviter d’en inventer le sens.
Tous les chantiers
Code
chantiers |>
dplyr:: arrange (date_debut) |>
dplyr:: transmute (Voie = voie, Arrondissement = ar, ` Maître d'ouvrage ` = maitre_ouvrage,
Objet = objet, Début = date_debut, Fin = date_fin,
` Impact ` = impact_circulation) |>
reactable:: reactable (
searchable = TRUE ,
filterable = TRUE ,
pagination = TRUE ,
defaultPageSize = 20 ,
compact = TRUE ,
resizable = TRUE ,
highlight = TRUE ,
wrap = TRUE ,
defaultColDef = reactable:: colDef (
align = "left" ,
headerStyle = list (fontWeight = "bold" ),
style = list (whiteSpace = "normal" , wordBreak = "break-word" )
),
columns = list (
Voie = reactable:: colDef (minWidth = 160 ),
Arrondissement = reactable:: colDef (minWidth = 70 , maxWidth = 110 ),
` Maître d'ouvrage ` = reactable:: colDef (minWidth = 130 ),
Objet = reactable:: colDef (minWidth = 130 ),
Début = reactable:: colDef (minWidth = 90 , maxWidth = 110 ),
Fin = reactable:: colDef (minWidth = 90 , maxWidth = 110 ),
Impact = reactable:: colDef (minWidth = 100 )
)
)
Source & données
Code
tibble:: tibble (
` ` = c ("Jeu de données" , "Producteur" , "Licence" , "Fichier" , "Mise à jour" , "Observations" ),
` ` = c (
"[Chantiers perturbants](https://opendata.paris.fr/explore/dataset/chantiers-perturbants/information/)" ,
"Direction de la Voirie et des Déplacements — Ville de Paris" ,
"Open Database License (ODbL)" ,
sprintf ("`data/paris/chantiers-perturbants.parquet` (%s ko) + `arrondissements.parquet`" ,
round (file.size (ch_path) / 1024 )),
format (as.Date (file.mtime (ch_path)), "%d %B %Y" ),
sprintf ("%d chantiers, %s à %s" , n_tot, format (min (chantiers$ date_debut, na.rm = TRUE ), "%Y" ),
format (max (chantiers$ date_fin, na.rm = TRUE ), "%Y" ))
)
) |>
gt:: gt () |> gt:: fmt_markdown (columns = ` ` ) |>
gt:: tab_options (table.width = "100%" , column_labels.hidden = TRUE )
Jeu de données
Chantiers perturbants
Producteur
Direction de la Voirie et des Déplacements — Ville de Paris
Licence
Open Database License (ODbL)
Fichier
data/paris/chantiers-perturbants.parquet (36 ko) + arrondissements.parquet
Mise à jour
05 septembre 2026
Observations
113 chantiers, 2018 à 2031