W3docs

Nuages de points Matplotlib en Python — Guide complet

Apprenez à créer et personnaliser des nuages de points en Python avec Matplotlib. Couvre couleur, taille, alpha, colorbars, groupes multiples et annotations.

La fonction scatter() de Matplotlib vous permet de visualiser la relation entre deux variables numériques en plaçant un marqueur à chaque point de données (x, y). Contrairement à un graphique en courbes, les nuages de points ne font aucune hypothèse sur l'ordre ou la continuité — chaque point est autonome. Cela en fait le choix privilégié pour explorer les corrélations, repérer les clusters et détecter les valeurs aberrantes.

Ce chapitre couvre tout, de votre premier nuage de points aux techniques professionnelles : encodage de couleur et de taille par point, transparence, colorbars, graphiques multi-groupes, annotations de points et enregistrement de fichiers prêts pour la publication.

Avant de commencer, assurez-vous que Matplotlib est installé :

pip install matplotlib

Si vous débutez avec Matplotlib, lisez d'abord les chapitres Introduction à Matplotlib et Premiers pas.

Quand utiliser un nuage de points

Utilisez un nuage de points lorsque :

  • Vous souhaitez explorer la corrélation entre deux variables numériques (taille vs. poids, heures d'étude vs. note à l'examen).
  • Vous devez détecter des clusters — des groupes de points qui se regroupent naturellement.
  • Vous souhaitez identifier des valeurs aberrantes — des points éloignés de la distribution principale.
  • Vous encodez une troisième variable via la taille ou la couleur du marqueur (un « graphique en bulles » est un nuage de points où la taille représente une troisième variable).

Évitez les nuages de points lorsqu'un axe représente des catégories non ordonnées — un graphique en barres est plus clair dans ce cas. Pour les tendances sur une variable continue ordonnée, un graphique en courbes est plus approprié.

Créer un nuage de points basique

Passez deux séquences de longueur égale — les valeurs x et les valeurs y — à plt.scatter() :

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [2, 4, 5, 4, 7, 8, 6, 9, 10, 12]

plt.scatter(x, y)

plt.title('Basic Scatter Plot')
plt.xlabel('X Values')
plt.ylabel('Y Values')

plt.tight_layout()
plt.show()

plt.tight_layout() évite que les étiquettes soient tronquées — adoptez-le comme réflexe avant chaque appel à show() ou savefig().

Personnaliser la taille des marqueurs

Le paramètre s contrôle la taille des marqueurs en points au carré (la valeur par défaut est 20). Augmentez-la pour rendre les points plus visibles, notamment lors de présentations :

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5, 6, 7, 8]
y = [3, 1, 4, 1, 5, 9, 2, 6]

plt.scatter(x, y, s=120)

plt.title('Larger Markers')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()

Vous pouvez aussi passer une liste ou un array à s pour que chaque point ait sa propre taille — c'est ainsi qu'on encode une troisième variable numérique comme surface de bulle :

import matplotlib.pyplot as plt

x      = [1, 2, 3, 4, 5]
y      = [5, 3, 6, 2, 7]
sizes  = [100, 300, 50, 400, 200]   # third variable encoded as bubble area

plt.scatter(x, y, s=sizes)

plt.title('Bubble Chart — size encodes a third variable')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()

Personnaliser la couleur des marqueurs

Une couleur unique pour tous les points

Passez un nom de couleur, une chaîne hexadécimale ou un tuple RGB à c (ou color) :

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5]
y = [2, 4, 1, 5, 3]

plt.scatter(x, y, s=100, c='steelblue')

plt.title('Single Color')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()

Couleur par point à partir d'une variable numérique

Passer un array à c associe chaque valeur à une couleur via la colormap spécifiée dans cmap. Ajoutez plt.colorbar() pour indiquer ce que représentent les couleurs :

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=42)
x      = rng.random(50)
y      = rng.random(50)
values = rng.random(50)          # third variable, e.g. intensity or temperature

scatter = plt.scatter(x, y, s=80, c=values, cmap='viridis')
plt.colorbar(scatter, label='Intensity')

plt.title('Color-Mapped Scatter Plot')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()

'viridis' est une colormap perceptuellement uniforme, lisible en niveaux de gris et accessible aux personnes daltoniennes. D'autres bons choix sont 'plasma', 'cividis' et 'coolwarm'.

Contrôler la transparence avec alpha

Lorsque de nombreux points se chevauchent, ils forment une masse opaque qui masque la densité réelle. Définissez alpha (0 = totalement transparent, 1 = totalement opaque) pour révéler la structure des chevauchements :

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=0)
x = rng.normal(loc=0, scale=1, size=300)
y = rng.normal(loc=0, scale=1, size=300)

plt.scatter(x, y, s=40, alpha=0.4)

plt.title('Transparent Markers Reveal Density (alpha=0.4)')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()

Un bon point de départ est alpha=0.4 à 0.6. Ajustez selon le nombre de points.

Styliser les bordures des marqueurs

Utilisez edgecolors pour ajouter une bordure autour de chaque marqueur, et linewidths pour contrôler l'épaisseur de la bordure. Cela aide les points à se distinguer sur un fond coloré :

import matplotlib.pyplot as plt

x = [1, 2, 3, 4, 5, 6]
y = [3, 1, 4, 1, 5, 9]

plt.scatter(x, y, s=150, c='gold', edgecolors='black', linewidths=1.5)

plt.title('Markers with Edges')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()

Passez edgecolors='none' pour supprimer complètement les bordures (c'est la valeur par défaut pour la plupart des colormaps).

Tracer plusieurs groupes

Pour comparer des groupes, appelez plt.scatter() une fois par groupe et attribuez un label. Matplotlib attribue automatiquement une couleur différente à chaque appel :

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=7)

# Group A — centered around (2, 3)
ax_x = rng.normal(loc=2, scale=0.5, size=30)
ax_y = rng.normal(loc=3, scale=0.5, size=30)

# Group B — centered around (5, 6)
bx_x = rng.normal(loc=5, scale=0.5, size=30)
bx_y = rng.normal(loc=6, scale=0.5, size=30)

# Group C — centered around (8, 2)
cx_x = rng.normal(loc=8, scale=0.5, size=30)
cx_y = rng.normal(loc=2, scale=0.5, size=30)

plt.scatter(ax_x, ax_y, s=60, label='Group A')
plt.scatter(bx_x, bx_y, s=60, label='Group B')
plt.scatter(cx_x, cx_y, s=60, label='Group C')

plt.legend()
plt.title('Multi-Group Scatter Plot')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()

Chaque appel à scatter() choisit automatiquement la couleur suivante dans le cycle de couleurs par défaut. Passez c='red' (ou toute autre couleur) pour la remplacer.

Annoter des points individuels

Utilisez plt.annotate() pour étiqueter des points spécifiques — utile pour mettre en évidence des valeurs aberrantes ou des observations clés :

import matplotlib.pyplot as plt

cities = ['London', 'Berlin', 'Madrid', 'Rome', 'Paris']
population = [9.0, 3.7, 3.3, 2.8, 2.1]   # millions
area       = [1572, 892, 604, 1285, 105]   # km²

plt.scatter(area, population, s=100, c='steelblue', edgecolors='black', linewidths=0.8)

for i, city in enumerate(cities):
    plt.annotate(
        city,
        xy=(area[i], population[i]),
        xytext=(8, 4),                      # offset in points
        textcoords='offset points',
        fontsize=9,
    )

plt.title('European City Population vs. Area')
plt.xlabel('Area (km²)')
plt.ylabel('Population (millions)')
plt.tight_layout()
plt.show()

Le motif xytext + textcoords='offset points' décale légèrement l'étiquette afin qu'elle ne se superpose pas directement au marqueur.

Utiliser des axes logarithmiques

Lorsque les données couvrent plusieurs ordres de grandeur, des axes linéaires compriment la plupart des points dans un coin. Passez à une échelle logarithmique avec plt.xscale('log') ou plt.yscale('log') :

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=1)
x = np.logspace(1, 5, 60)            # 10¹ to 10⁵
y = x * rng.uniform(0.5, 2.0, 60)   # roughly proportional, with noise

plt.scatter(x, y, s=40, alpha=0.7)
plt.xscale('log')
plt.yscale('log')

plt.title('Log-Scale Scatter Plot')
plt.xlabel('X (log scale)')
plt.ylabel('Y (log scale)')
plt.tight_layout()
plt.show()

Les deux axes couvrent désormais des intervalles réguliers de puissances de dix, répartissant uniformément les données sur la zone du graphique.

Ajouter une droite de régression

Un nuage de points montre les points individuels ; l'ajout d'une droite de régression révèle la tendance générale. Calculez la pente et l'ordonnée à l'origine avec np.polyfit() :

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=3)
x = np.linspace(0, 10, 40)
y = 2.5 * x + rng.normal(scale=3, size=40)   # linear trend + noise

# Fit a degree-1 polynomial (straight line)
slope, intercept = np.polyfit(x, y, 1)
trend_line = slope * x + intercept

plt.scatter(x, y, s=50, label='Data points', alpha=0.7)
plt.plot(x, trend_line, color='red', linewidth=2, label=f'Trend (slope={slope:.2f})')

plt.legend()
plt.title('Scatter Plot with Regression Line')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()
plt.show()

np.polyfit(x, y, 1) renvoie [slope, intercept] pour la droite de meilleur ajustement passant par les points.

Enregistrer un nuage de points dans un fichier

Utilisez plt.savefig() à la place de plt.show() pour écrire le graphique sur le disque. Appelez-le avant plt.show() — après show(), la figure est effacée :

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=9)
x = rng.random(60)
y = rng.random(60)

plt.scatter(x, y, s=60, alpha=0.6, c='teal', edgecolors='white', linewidths=0.5)
plt.title('Saved Scatter Plot')
plt.xlabel('X')
plt.ylabel('Y')
plt.tight_layout()

plt.savefig('scatter.png', dpi=150)   # PNG at 150 DPI
plt.savefig('scatter.pdf')             # vector PDF — best for publication
plt.show()

Options de format courantes : 'png' (raster, web), 'pdf' (vectoriel, publication), 'svg' (vectoriel, web). Augmentez dpi à 300 pour des rasters de qualité impression.

scatter() vs plot() — Lequel utiliser ?

Les deux fonctions peuvent tracer des graphiques composés uniquement de marqueurs, mais elles servent des objectifs différents :

Fonctionnalitéplt.scatter()plt.plot()
Taille par point (s)Oui — passer un arrayNon
Couleur par point (c)Oui — passer un arrayNon (une couleur par appel)
Support de colormapOui (cmap)Limité
Performance sur grands jeux de donnéesPlus lentPlus rapide
Ligne de connexionNonOui

Utilisez scatter() lorsque vous avez besoin d'un style par point (couleur ou taille variant selon les données). Utilisez plot(marker='o', linestyle='None') pour des graphiques à marqueurs simples sur de grands jeux de données où la vitesse est importante. Consultez le chapitre Marqueurs Matplotlib pour en savoir plus sur les styles de marqueurs.

Exemple complet

Le script autonome suivant combine les techniques les plus utiles — mappage de couleurs, encodage de taille, transparence, colorbar et légende :

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng(seed=42)

n = 80
x      = rng.standard_normal(n)
y      = 0.8 * x + rng.standard_normal(n) * 0.6   # correlated
sizes  = rng.uniform(30, 200, n)                   # bubble area
values = rng.random(n)                             # third variable for color

fig, ax = plt.subplots(figsize=(8, 5))

sc = ax.scatter(
    x, y,
    s=sizes,
    c=values,
    cmap='plasma',
    alpha=0.75,
    edgecolors='white',
    linewidths=0.5,
)

plt.colorbar(sc, ax=ax, label='Intensity')

ax.set_title('Comprehensive Scatter Plot Example', fontsize=13)
ax.set_xlabel('X Variable')
ax.set_ylabel('Y Variable (correlated)')
fig.tight_layout()
plt.savefig('scatter_complete.png', dpi=150)
plt.show()

Points clés :

  • fig, ax = plt.subplots() vous donne des objets figure et axes explicites — l'approche recommandée pour tout ce qui dépasse un prototype rapide.
  • ax.scatter() sur un objet Axes se comporte de manière identique à plt.scatter().
  • plt.colorbar(sc, ax=ax, label='...') attache la colorbar aux axes spécifiques.

Bonnes pratiques

  • Montrez l'échelle. Si vous utilisez c avec une colormap, ajoutez toujours une colorbar pour que les lecteurs sachent ce que représentent les couleurs.
  • Évitez le surtraçage. Pour plus de ~500 points, définissez alpha < 1 ou passez à un histogramme 2D (plt.hist2d()) ou un graphique hexbin (plt.hexbin()).
  • Choisissez des colormaps accessibles. 'viridis', 'plasma' et 'cividis' sont perceptuellement uniformes et adaptées aux daltoniens. Évitez 'jet' et 'rainbow'.
  • Étiquetez les axes avec des unités. plt.xlabel('Taille (cm)') est plus informatif que plt.xlabel('Taille').
  • Ajoutez un titre qui énonce la conclusion. « Taille vs. Poids — corrélation positive » est plus utile que « Nuage de points ».

Chapitres associés

Was this page helpful?