Cartographier les prix immobiliers avec DVF

Les ventes immobilières en données ouvertes : éviter le piège des lignes multiples, calculer un prix au m² fiable, en faire une choroplèthe et respecter les règles d'usage de DVF.

Combien se vendent les appartements dans votre quartier ? Depuis 2019, les « Demandes de valeurs foncières » (DVF) de l'administration fiscale sont en données ouvertes : toutes les ventes immobilières des dernières années, avec leur prix, leur surface et leur parcelle. Ce tutoriel montre comment passer de ce fichier brut, plein de pièges, à une carte des prix au m² juste et lisible, dans le respect des règles d'usage de ces données.

Ce que contient DVF

DVF recense les mutations (ventes, ventes sur plan, échanges, adjudications) enregistrées par les services de la publicité foncière, sur une période glissante d'environ cinq ans. Trois territoires manquent : le Bas-Rhin, le Haut-Rhin et la Moselle, qui relèvent du livre foncier, ainsi que Mayotte. Le nom des acheteurs et des vendeurs n'y figure jamais.

VersionProducteurIntérêt
DVF brutDGFiPLe fichier d'origine, au format texte, peu pratique
DVF géolocaliséesEtalabCSV par commune, département et année, avec la parcelle, la longitude et la latitude : le plus simple à cartographier
DVF+CeremaVersion restructurée et enrichie, pensée pour les études foncières

Les fichiers d'Etalab se téléchargent commune par commune :

https://files.data.gouv.fr/geo-dvf/latest/csv/2024/communes/74/74010.csv   (Annecy, ventes 2024)

L'explorateur app.dvf.etalab.gouv.fr permet aussi de consulter les ventes parcelle par parcelle.

Le piège principal : une ligne n'est pas une vente

Le fichier compte une ligne par bien et par parcelle : un appartement avec sa cave et son parking produit trois lignes. Une vente en bloc en produit des dizaines. Or la colonne valeur_fonciere porte le prix de toute la vente, répété sur chaque ligne. À Annecy en 2024, le fichier compte 6 426 lignes pour seulement 2 683 ventes. L'une d'elles s'étale sur 107 lignes qui répètent chacune son prix de 16,6 millions d'euros : additionner les lignes compterait plus de 1,7 milliard.

ColonneUtilité
id_mutationIdentifiant de la vente : à utiliser pour regrouper les lignes
nature_mutationVente, Vente en l'état futur d'achèvement (VEFA, logements neufs sur plan), Échange, Adjudication…
valeur_foncierePrix total de la vente, frais de notaire exclus
type_localMaison, Appartement, Dépendance, Local industriel ou commercial, vide pour un terrain
surface_reelle_batiSurface bâtie déclarée (et lot1_surface_carrez pour la surface Carrez des lots)
id_parcelleIdentifiant de 14 caractères de la parcelle (voir le tutoriel sur le cadastre)

Calculer un prix au m² fiable

La méthode la plus sûre est de ne garder que les ventes simples, où le prix correspond à un seul logement :

  1. Regrouper les lignes par id_mutation.
  2. Ne garder que les ventes (sans les VEFA, dont les prix de neuf faussent la comparaison avec l'ancien, à étudier à part).
  3. Ne garder que les ventes d'un seul appartement ou d'une seule maison. Les dépendances (cave, garage) sont admises ; les locaux commerciaux sont exclus.
  4. Écarter les valeurs aberrantes : surfaces minuscules, prix symboliques, prix au m² hors de toute plausibilité.
  5. Agréger par zone avec la médiane, moins sensible aux extrêmes que la moyenne, et ne rien publier pour une zone qui compte trop peu de ventes.
import pandas as pd

dvf = pd.read_csv("74010.csv", dtype={"id_parcelle": str, "code_commune": str})
ventes = dvf[dvf.nature_mutation == "Vente"]

# Une vente = un seul logement (dépendances admises), pas de local commercial
logements = ventes[ventes.type_local.isin(["Appartement", "Maison"])]
nb = logements.groupby("id_mutation").size()
autres = ventes[~ventes.type_local.isin(["Appartement", "Maison", "Dépendance"]) & ventes.type_local.notna()]
ok = nb[nb == 1].index.difference(autres.id_mutation)
simples = logements[logements.id_mutation.isin(ok)].copy()

simples["prix_m2"] = simples.valeur_fonciere / simples.surface_reelle_bati
simples = simples[(simples.surface_reelle_bati >= 9) & simples.prix_m2.between(500, 30000)]

# Médiane par section cadastrale (préfixe + section), sections d'au moins 5 ventes
simples["section"] = simples.id_parcelle.str[5:10]
stats = simples.groupby("section").prix_m2.agg(["median", "count"])
stats = stats[stats["count"] >= 5]

Sur Annecy en 2024, cette méthode retient 1 537 ventes sur 2 683. Elle produit une médiane par section cadastrale, de 3 300 à 9 400 €/m² selon les quartiers.

La carte : une choroplèthe

Le prix au m² est un taux : il se représente en aplats de couleur (choroplèthe), avec une palette séquentielle. Les règles du tutoriel de sémiologie graphique s'appliquent : 5 à 7 classes, discrétisation par quantiles ou seuils naturels, et une légende qui indique la source, la période et le nombre de ventes. Pour le fond géographique, joignez vos statistiques aux sections cadastrales d'Etalab (cadastre-74010-sections.json.gz) par le préfixe et la section. À une échelle plus large, utilisez les IRIS de l'INSEE.

L'outil Palettes et styles de carte calcule les classes sur votre fichier et exporte le style pour QGIS ou MapLibre.

Les règles d'usage de DVF

DVF est en libre accès, mais sa réutilisation est encadrée par le décret n° 2018-1350 du 28 décembre 2018 : les données ne doivent pas permettre de réidentifier les personnes concernées par les ventes, et elles ne doivent pas être indexées par les moteurs de recherche. Publier une liste de ventes individuelles sur un site public, adresse par adresse, est donc à proscrire. Des statistiques agrégées (médianes par quartier, sur un nombre suffisant de ventes) ne posent pas ce problème : c'est ce que montre la démonstration ci-dessous.

Démonstration

La médiane du prix au m² des logements vendus à Annecy en 2024, par section cadastrale. Seules les données agrégées sont publiées, pour les sections d'au moins 5 ventes. Le volet « Votre commune » traite le fichier DVF que vous téléchargez, entièrement dans votre navigateur.

À essayer : comparez appartements et maisons, et repérez l'écart entre la vieille ville et le bord du lac d'une part, et les quartiers périphériques d'autre part. Dans « Votre commune », saisissez le nom, le code postal ou le code INSEE de la commune, choisissez-la dans la liste, téléchargez le fichier, puis déposez-le : la même méthode s'applique à votre territoire. Le fichier déposé n'est envoyé sur aucun serveur.

Licences : textes et schémas sous licence CC BY-SA 4.0 (réutilisation libre en citant CartoForge et en partageant à l'identique) ; extraits de code sous licence MIT, à copier librement dans vos projets.
Liens, services et noms de couches vérifiés le 15/10/2026. Un lien cassé ? Signalez-le.