library(ggplot2)
ggplot(diamonds, aes(x = carat, y = price)) +
geom_point() +
theme_minimal()
Corrigez un nuage de points surchargé sur des données volumineuses avec le binning et la densité 2D
Quand un nuage de points se transforme en bloc noir sur un grand jeu de données, passez à une vue de densité 2D ou en bins. Construisez des bins rectangulaires avec geom_bin2d(), des bins hexagonaux avec geom_hex(), des lignes de contour avec geom_density_2d() et une surface de densité remplie avec stat_density_2d() — le tout dans ggplot2.
27 juin 2026
11 juillet 2026
geom_bin2d() divise le plan en rectangles et colore chacun selon son effectif (une heatmap 2D des effectifs de bins).geom_hex() fait de même avec des hexagones, évitant les artefacts d’alignement des bins carrés (nécessite le package hexbin).geom_density_2d() trace des lignes de contour à partir d’une estimation de densité par noyau en 2D ; stat_density_2d(geom = "polygon") la remplit.Un nuage de points fonctionne à merveille pour quelques centaines de points. Poussez-le à des dizaines de milliers et il s’effondre : les points s’empilent les uns sur les autres jusqu’à ce que la région la plus dense ne soit plus qu’un bloc noir, et vous ne pouvez plus dire où vit réellement la majeure partie de vos données. C’est la surcharge (overplotting).
La solution consiste à cesser de dessiner des points individuels et à montrer plutôt la densité. Cette leçon couvre quatre outils ggplot2 pour cela, tous sur l’exemple classique de données volumineuses — le jeu de données diamonds (53 940 lignes de carat versus prix) :
geom_bin2d(),geom_hex(),geom_density_2d(),stat_density_2d().Commencez par observer le problème. Tracez le carat de chaque diamant en fonction de son price :
Le coin inférieur gauche est un bloc d’encre compact. Y a-t-il 100 diamants là ou 10 000 ? Le graphique ne peut pas le dire. Chaque technique ci-dessous répond à cette question.
geom_bin2d() découpe la zone de tracé en une grille de rectangles, compte combien de points tombent dans chacun, et remplit chaque rectangle selon cet effectif — une heatmap 2D. Contrôlez la grille avec bins (le nombre de bins le long de chaque axe ; la valeur par défaut est 30). Associez le remplissage à une échelle viridis pour que le gradient d’effectifs se lise correctement.

La structure est maintenant évidente : la plupart des diamants sont petits et bon marché (coin inférieur gauche lumineux), s’amincissant vers l’extrémité grande et coûteuse. geom_bin2d() est stat_bin2d() avec une géométrie par défaut — vous pouvez appeler l’un ou l’autre ; la forme geom est celle vers laquelle vous vous tournez.
Les bins carrés peuvent créer des bandes verticales et horizontales visibles parce que leurs bords s’alignent parfaitement. Les hexagones pavent le plan sans cet alignement régulier, si bien que geom_hex() donne souvent une lecture plus lisse et plus honnête de la densité. Il nécessite l’installation du package hexbin.

Même histoire, des tuiles plus nettes. Baissez bins pour des hexagones plus grossiers et plus marqués ; augmentez-le pour plus de détail. Comme geom_hex() dépend d’un package compilé, il s’exécute au moment du build ici — le bac à sable en direct à la fin de la leçon s’en tient à des alternatives purement ggplot2 pour démarrer rapidement dans votre navigateur.
Au lieu de compter les points dans des cellules, vous pouvez estimer une densité 2D lisse et tracer ses lignes de contour — comme les courbes de niveau sur une carte topographique. geom_density_2d() fait cela. Il se lit bien superposé à un nuage de points discret, vous conservez donc les points bruts et la densité.

Les anneaux serrés et imbriqués marquent le cœur de haute densité ; les anneaux largement espacés marquent les régions clairsemées.
Pour remplir les contours plutôt que les tracer en silhouette, utilisez stat_density_2d() avec geom = "polygon" et associez le remplissage au niveau (level) de densité calculé. Dans le ggplot2 actuel, vous référencez une variable calculée par un stat avec after_stat() :

Cela donne un « îlot de chaleur » rempli là où les données se concentrent. Cela fonctionne aussi sur des données plus petites — remplacez par faithful (les éruptions de l’Old Faithful) pour voir clairement la forme à deux groupes :

Les deux pics remplis sont les deux modes d’éruption — une structure que le nuage de points brut ne fait qu’esquisser.
Modifiez le code et appuyez sur Run — il s’exécute dans votre navigateur via webR (sans serveur, sans installation). Ce bac à sable utilise le binning et les contours purement ggplot2 (geom_bin2d + geom_density_2d) pour démarrer rapidement ; geom_hex nécessite le package compilé hexbin et est rendu pour vous ci-dessus.
Vous travaillez en Python ? Un guide de densité 2D matplotlib/seaborn arrive bientôt dans la série Python.
Demandez à Prova « quand devrais-je utiliser geom_hex plutôt que geom_bin2d ? » — elle répond avec du code que vous pouvez exécuter, donc l’explication est reproductible. The runtime is the judge. Demander à Prova →
geom_hex() génère l’erreur « Computation failed … could not find function ». geom_hex() dépend du package hexbin. Installez-le une fois avec install.packages("hexbin"), puis rechargez ggplot2. (C’est aussi pourquoi le bac à sable en direct ci-dessus évite geom_hex.)
..level.. déclenche un avertissement de dépréciation. Les tutoriels plus anciens écrivent aes(fill = ..level..). Le ggplot2 actuel veut aes(fill = after_stat(level)) — même résultat, sans avertissement.
Les bins semblent trop grossiers ou trop fins. Il n’existe pas de nombre de bins universellement « correct ». Ajustez bins (un seul nombre, ou un vecteur de longueur 2 pour des résolutions x/y différentes) jusqu’à ce que la structure soit visible mais pas bruitée — commencez à 30 et ajustez.
Cessez de dessiner des points individuels et montrez plutôt la densité. Découpez le plan en bins et colorez par effectif avec geom_bin2d() (rectangles) ou geom_hex() (hexagones), ou estimez une densité lisse avec geom_density_2d() (contours) / stat_density_2d() (remplie). Des correctifs plus légers comme alpha et une size de point plus petite aident un peu, mais le binning est la vraie réponse pour des dizaines de milliers de points.
Tous deux divisent le plan en cellules et colorent chaque cellule selon le nombre de points qu’elle contient. geom_bin2d() utilise des rectangles ; geom_hex() utilise des hexagones. Les hexagones évitent les artefacts d’alignement horizontal/vertical réguliers que les bins carrés peuvent créer, si bien que geom_hex() se lit souvent plus lisse — mais il nécessite le package hexbin.
Pour les lignes de contour, utilisez geom_density_2d() ; pour une surface remplie, utilisez stat_density_2d(aes(fill = after_stat(level)), geom = "polygon") plus une échelle de remplissage telle que scale_fill_viridis_c(). Les deux effectuent une estimation de densité par noyau en 2D et sont de bonnes alternatives à un nuage de points lorsque les points se chevauchent.
La cause habituelle est l’absence du package hexbin — geom_hex() ne peut pas calculer ses bins sans lui. Exécutez install.packages("hexbin") et redémarrez votre session. Dans un runtime navigateur/WASM (comme un bac à sable intégré à la page), le package compilé peut être indisponible ; utilisez donc geom_bin2d() à la place.
Définissez l’argument bins : geom_bin2d(bins = 50) ou geom_hex(bins = 15). Passez un seul nombre pour la même résolution sur les deux axes, ou un vecteur de longueur 2 comme bins = c(40, 20) pour binner x et y différemment.
Le graphique ci-dessous surcharge. Remplacez geom_point() par une couche de binning rectangulaire qui colore chaque bin selon son effectif, et ajoutez un remplissage viridis.
Quel appel dessine une densité 2D remplie (et pas seulement des lignes de contour) ?
geom_density_2d()geom_bin2d()stat_density_2d(aes(fill = after_stat(level)), geom = "polygon")c. stat_density_2d() avec geom = "polygon" et le remplissage associé à after_stat(level) remplit la densité. geom_density_2d() ne dessine que les lignes de contour, et geom_bin2d() produit une heatmap d’effectifs rectangulaire.
Quand un nuage de points surcharge sur un grand jeu de données, passez à la densité. geom_bin2d() et geom_hex() vous donnent une heatmap d’effectifs en rectangles ou en hexagones ; geom_density_2d() et stat_density_2d() vous donnent des lignes de contour ou une surface remplie à partir d’une estimation de densité par noyau. Une échelle viridis garde le gradient honnête et adaptée au daltonisme.
Vous préférez un livre ? GGPlot2 Essentials est disponible en PDF téléchargeable — toutes les leçons de cette série, hors ligne et à vous.
Prouvez que vous savez le faire. Maîtrisez toute la série ggplot2 — suivez votre parcours, construisez des projets et obtenez un certificat.
Passez à Pro — Prova illimité sur vos propres données et un certificat vérifiable qui atteste la compétence.
dès 15 $/mois facturé annuellement
✓ Vous êtes Pro — continuez. The runtime is the judge.
Prêt à passer à la vitesse supérieure ?
Recevez les nouvelles leçons R & Python par e-mail
Pratique, reproductible, sans spam. Désinscription à tout moment.
Double opt-in. Nous ne partageons jamais votre e-mail.
Cette leçon est reproductible : chaque figure a été produite par le code affiché (si elle s’affiche, le code fonctionne), et le bac à sable se ré-exécute en direct dans votre navigateur. The runtime is the judge.
@online{2026,
author = {},
title = {Graphique de densité 2D en R : geom\_hex, geom\_bin2d \&
contours},
date = {2026-06-27},
url = {https://www.datanovia.com/learn/data-visualization/ggplot2/2d-density-hexbin},
langid = {fr}
}