Verbalisations de la police municipale

Données - Ville de Paris

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

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

verb_path <- here::here("data", "paris", "dpmp-verbalisations.parquet")
verb <- arrow::read_parquet(verb_path) |>
  dplyr::mutate(ar = suppressWarnings(as.integer(substr(arrondissement, 4, 5))))

n_lignes <- nrow(verb)
n_tot    <- sum(verb$nb_verbalisation, na.rm = TRUE)
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())

La Direction de la Police Municipale et de la Prévention verbalise deux grandes familles d’infractions : la protection routière (stationnement gênant, conduite dangereuse…) et la lutte contre les incivilités (dépôts sauvages, nuisances sonores, épanchement d’urine…). 5 915 372 verbalisations depuis 2022, agrégées par trimestre, arrondissement et catégorie d’infraction (89 122 lignes).

Code
verb |>
  dplyr::arrange(dplyr::desc(periode)) |>
  dplyr::transmute(Trimestre = trimestre_annee, Arrondissement = ar,
                   `Type` = type_infraction, Catégorie = categorie_infraction,
                   Verbalisations = nb_verbalisation) |>
  head(8) |>
  gt::gt() |>
  gt::tab_header(title = "8 lignes les plus récentes") |>
  gt::tab_options(table.width = "100%")
8 lignes les plus récentes
Trimestre Arrondissement Type Catégorie Verbalisations
2026 T2 12 Lutte contre les incivilités Présentation irrégulière à la collecte 161
2026 T2 20 Protection routière Conduite - Voitures, poids-lourds ... 34
2026 T2 18 Lutte contre les incivilités Infraction liée aux animaux 1
2026 T2 9 Protection routière Stationnement gênant - 2 RM 22
2026 T2 19 Protection routière Conduite - Voitures, poids-lourds ... 882
2026 T2 11 Lutte contre les incivilités Etalages et terrasses 36
2026 T2 11 Lutte contre les incivilités Infraction liée à un chantier 3
2026 T2 12 Protection routière Infraction liée aux véhicules - 2 RM 4

Évolution

Code
verb |>
  dplyr::group_by(periode, type_infraction) |>
  dplyr::summarise(n = sum(nb_verbalisation, na.rm = TRUE), .groups = "drop") |>
  dplyr::filter(!is.na(type_infraction)) |>
  ggplot(aes(periode, n, colour = type_infraction)) +
  geom_line(linewidth = 1) +
  geom_point(size = 2) +
  scale_colour_manual(values = c("Protection routière" = "#3b6f8a",
                                 "Lutte contre les incivilités" = "#c0392b"), name = NULL) +
  scale_y_continuous(labels = scales::label_number(big.mark = " ")) +
  labs(title = "Verbalisations par mois", x = NULL, y = NULL) +
  theme_barres +
  theme(legend.position = "bottom")

Par catégorie d’infraction

Code
verb |>
  dplyr::filter(!is.na(categorie_infraction)) |>
  dplyr::group_by(categorie_infraction, type_infraction) |>
  dplyr::summarise(n = sum(nb_verbalisation, na.rm = TRUE), .groups = "drop") |>
  dplyr::mutate(categorie_infraction = forcats::fct_reorder(categorie_infraction, n)) |>
  ggplot(aes(n, categorie_infraction, fill = type_infraction)) +
  geom_col(width = 0.7) +
  geom_text(aes(label = scales::number(n, big.mark = " ", scale = 1e-3, suffix = "k")),
            hjust = -0.15, size = 2.8) +
  scale_fill_manual(values = c("Protection routière" = "#3b6f8a",
                               "Lutte contre les incivilités" = "#c0392b"), name = NULL) +
  scale_x_continuous(labels = scales::label_number(big.mark = " "), expand = expansion(mult = c(0, 0.15))) +
  labs(title = "Verbalisations cumulées par catégorie (depuis 2022)", x = NULL, y = NULL) +
  theme_barres +
  theme(legend.position = "bottom")

Par arrondissement

Code
cnt <- verb |> dplyr::filter(!is.na(ar)) |> dplyr::group_by(ar) |>
  dplyr::summarise(n = sum(nb_verbalisation, na.rm = TRUE), .groups = "drop")

arr_sf |>
  dplyr::left_join(cnt, by = c("c_ar" = "ar")) |>
  ggplot() +
  geom_sf(aes(fill = n), colour = "white", linewidth = 0.2) +
  scale_fill_viridis_c(option = "rocket", direction = -1, na.value = "grey92",
                       labels = scales::label_number(big.mark = " ", scale = 1e-3, suffix = "k"),
                       name = "Verbalisations\n(depuis 2022)") +
  labs(title = "Verbalisations cumulées par arrondissement") +
  theme_carte

Détail par catégorie et année

Code
verb |>
  dplyr::mutate(annee = as.integer(format(annee, "%Y"))) |>
  dplyr::group_by(Année = annee, Type = type_infraction, Catégorie = categorie_infraction) |>
  dplyr::summarise(Verbalisations = sum(nb_verbalisation, na.rm = TRUE), .groups = "drop") |>
  dplyr::arrange(dplyr::desc(Année), dplyr::desc(Verbalisations)) |>
  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(
      Année = reactable::colDef(minWidth = 70, maxWidth = 90),
      Type = reactable::colDef(minWidth = 150),
      Catégorie = reactable::colDef(minWidth = 220),
      Verbalisations = reactable::colDef(minWidth = 90, maxWidth = 130, align = "right",
                                        format = reactable::colFormat(separators = TRUE))
    )
  )

Agrégé par année et catégorie ; le détail complet (par trimestre et arrondissement) est dans le fichier source.

Source & données

Code
tibble::tibble(
  ` ` = c("Jeu de données", "Producteur", "Licence", "Fichier", "Mise à jour", "Observations"),
  `  ` = c(
    "[Verbalisations](https://opendata.paris.fr/explore/dataset/dpmp-verbalisations/information/)",
    "Direction de la Police Municipale et de la Prévention — Ville de Paris",
    "Open Database License (ODbL)",
    sprintf("`data/paris/dpmp-verbalisations.parquet` (%s ko) + `arrondissements.parquet`",
            round(file.size(verb_path) / 1024)),
    format(as.Date(file.mtime(verb_path)), "%d %B %Y"),
    sprintf("%s lignes, %s verbalisations, 2022-2026", format(n_lignes, big.mark = " "),
            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 Verbalisations
Producteur Direction de la Police Municipale et de la Prévention — Ville de Paris
Licence Open Database License (ODbL)
Fichier data/paris/dpmp-verbalisations.parquet (357 ko) + arrondissements.parquet
Mise à jour 05 septembre 2026
Observations 89 122 lignes, 5 915 372 verbalisations, 2022-2026