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 matplotlibSi 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 array | Non |
Couleur par point (c) | Oui — passer un array | Non (une couleur par appel) |
| Support de colormap | Oui (cmap) | Limité |
| Performance sur grands jeux de données | Plus lent | Plus rapide |
| Ligne de connexion | Non | Oui |
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 objetAxesse 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
cavec 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 < 1ou 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 queplt.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
- Introduction à Matplotlib — aperçu de la bibliothèque et installation
- Premiers pas avec Matplotlib — vos premiers graphiques
- Graphiques en courbes Matplotlib — tendances sur des variables continues
- Graphiques en barres Matplotlib — comparaison de catégories discrètes
- Histogrammes Matplotlib — distribution d'une seule variable
- Marqueurs Matplotlib — tous les styles de marqueurs et options de personnalisation
- Sous-graphiques Matplotlib — combiner plusieurs graphiques dans une seule figure