Comprendre le nuage de points en Python
Créez et lisez des nuages de points en Python avec Matplotlib et Seaborn. Corrélation, encodage couleur, droite de régression et cas d'usage ML.
Un nuage de points place un point à chaque paire (x, y) d'un jeu de données. Le nuage de points ainsi formé révèle si deux variables numériques sont liées, à quel degré et dans quelle direction — ce qui rend les nuages de points indispensables pour l'analyse exploratoire des données et les workflows d'apprentissage automatique.
Ce chapitre couvre :
- Ce que montrent les nuages de points et comment les lire
- Créer des nuages de points avec Matplotlib et Seaborn
- Personnaliser les couleurs, les tailles et la transparence
- Encoder une troisième variable par la couleur ou la taille (graphiques à bulles)
- Tracer plusieurs groupes avec une légende
- Ajouter une droite de tendance par régression
- Cas d'usage courants en apprentissage automatique
Ce que montre un nuage de points
Chaque point représente une observation. L'axe horizontal porte une variable, l'axe vertical en porte une autre. La forme générale du nuage indique la corrélation entre les deux variables.
Lire le motif
| Motif | Signification |
|---|---|
| Les points montent de gauche à droite | Corrélation positive — quand X augmente, Y tend à augmenter |
| Les points descendent de gauche à droite | Corrélation négative — quand X augmente, Y tend à diminuer |
| Aucune forme discernable | Aucune corrélation linéaire entre les variables |
| Bande étroite et serrée | Corrélation forte |
| Nuage large et diffus | Corrélation faible |
| Points éloignés du nuage principal | Valeurs aberrantes — méritent d'être examinées |
Le coefficient de corrélation de Pearson r résume ce motif en un seul nombre allant de -1 (parfaitement négatif) à +1 (parfaitement positif). Une valeur proche de 0 signifie l'absence de relation linéaire. Les nuages de points vous permettent de voir ce que r ne peut pas vous dire — par exemple, deux jeux de données peuvent partager le même r tout en ayant des formes complètement différentes (voir le quartet d'Anscombe).
Créer un nuage de points avec Matplotlib
La fonction plt.scatter() de Matplotlib est l'option la plus flexible. Installez Matplotlib si ce n'est pas déjà fait :
pip install matplotlib numpyExemple de base
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=42)
# Simulate hours studied vs exam score
hours = rng.uniform(1, 10, 40)
score = 5 * hours + rng.normal(scale=8, size=40)
plt.scatter(hours, score)
plt.xlabel('Hours Studied')
plt.ylabel('Exam Score')
plt.title('Hours Studied vs Exam Score')
plt.tight_layout()
plt.show()La pente positive du nuage résultant montre qu'un plus grand nombre d'heures d'étude est corrélé avec de meilleurs résultats à l'examen.
Personnaliser la couleur et la taille des marqueurs
Les trois paramètres les plus utiles de plt.scatter() sont :
c— nom de couleur, chaîne hexadécimale, ou tableau de valeurs (mappé via une palette de couleurs)s— taille du marqueur en points au carré (20 par défaut) ; passer un scalaire ou un tableaualpha— transparence de 0 (invisible) à 1 (opaque) ; utiliser 0.4–0.7 pour les points qui se chevauchent
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=7)
x = rng.normal(loc=5, scale=2, size=60)
y = rng.normal(loc=5, scale=2, size=60)
plt.scatter(x, y, c='steelblue', s=80, alpha=0.6, edgecolors='white', linewidths=0.5)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Customized Scatter Plot')
plt.tight_layout()
plt.show()edgecolors='white' avec linewidths=0.5 ajoute une fine bordure blanche autour de chaque point, facilitant la distinction des points individuels lorsqu'ils se chevauchent.
Encoder une troisième variable par la couleur
Passez un tableau à c pour colorer chaque point selon une troisième variable numérique. Ajoutez plt.colorbar() pour que les lecteurs comprennent ce que les couleurs représentent :
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=3)
x = rng.random(50)
y = rng.random(50)
temperature = rng.uniform(15, 35, 50) # third variable, e.g. temperature in °C
scatter = plt.scatter(x, y, c=temperature, cmap='coolwarm', s=80, alpha=0.8)
plt.colorbar(scatter, label='Temperature (°C)')
plt.xlabel('Longitude')
plt.ylabel('Latitude')
plt.title('Sensor Readings by Temperature')
plt.tight_layout()
plt.show()Utilisez des palettes perceptuellement uniformes — 'viridis', 'plasma', 'cividis', ou 'coolwarm' — plutôt que 'jet' ou 'rainbow', qui déforment la perception et ne sont pas adaptées aux daltoniens.
Encoder une troisième variable par la taille des bulles
Passez un tableau à s pour rendre la surface de chaque marqueur proportionnelle à une troisième variable — c'est ce qu'on appelle un graphique à bulles :
import matplotlib.pyplot as plt
import numpy as np
countries = ['USA', 'China', 'Japan', 'Germany', 'UK']
gdp = [25.5, 18.0, 4.2, 4.1, 3.1] # trillion USD
life_exp = [76.4, 77.1, 84.3, 80.6, 81.3] # years
population = [334, 1412, 125, 84, 67] # millions — encoded as size
# Scale population to a visible marker area range
sizes = [p * 1.5 for p in population]
plt.scatter(gdp, life_exp, s=sizes, alpha=0.6, edgecolors='black', linewidths=0.8)
for i, name in enumerate(countries):
plt.annotate(name, (gdp[i], life_exp[i]), textcoords='offset points',
xytext=(6, 4), fontsize=9)
plt.xlabel('GDP (trillion USD)')
plt.ylabel('Life Expectancy (years)')
plt.title('GDP vs Life Expectancy (bubble size = population)')
plt.tight_layout()
plt.show()Créer un nuage de points avec Seaborn
La fonction sns.scatterplot() de Seaborn fonctionne directement avec les DataFrames Pandas et ajoute des fonctionnalités telles que le regroupement automatique par colonne catégorielle et un paramètre hue intégré pour l'encodage couleur.
Installez Seaborn d'abord :
pip install seaborn pandasNuage de points Seaborn de base
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
data = pd.DataFrame({
'hours': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'score': [45, 50, 55, 60, 65, 70, 72, 80, 85, 92],
})
sns.scatterplot(data=data, x='hours', y='score')
plt.xlabel('Hours Studied')
plt.ylabel('Exam Score')
plt.title('Hours Studied vs Exam Score')
plt.tight_layout()
plt.show()Colorier les groupes avec hue
Le paramètre hue attribue automatiquement une couleur différente à chaque catégorie et ajoute une légende :
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
data = pd.DataFrame({
'sepal_length': [5.1, 4.9, 6.3, 5.8, 7.0, 6.4, 6.3, 5.8, 7.1, 6.3],
'sepal_width': [3.5, 3.0, 2.9, 2.7, 3.2, 3.2, 3.3, 2.7, 3.0, 2.9],
'species': ['setosa', 'setosa', 'versicolor', 'versicolor',
'virginica', 'virginica', 'virginica', 'versicolor',
'virginica', 'virginica'],
})
sns.scatterplot(data=data, x='sepal_length', y='sepal_width', hue='species')
plt.title('Iris: Sepal Length vs Sepal Width')
plt.tight_layout()
plt.show()Seaborn crée automatiquement la légende. C'est équivalent à appeler plt.scatter() plusieurs fois avec des couleurs différentes.
Ajouter une droite de régression avec sns.regplot()
sns.regplot() combine un nuage de points avec une droite de régression ajustée et un intervalle de confiance :
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=10)
x = np.linspace(1, 10, 30)
y = 3 * x + rng.normal(scale=4, size=30)
data = pd.DataFrame({'x': x, 'y': y})
sns.regplot(data=data, x='x', y='y', scatter_kws={'alpha': 0.6}, line_kws={'color': 'red'})
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Scatter Plot with Regression Line')
plt.tight_layout()
plt.show()La zone ombrée autour de la droite est un intervalle de confiance à 95 %. Utilisez ci=None pour le supprimer.
Tracer plusieurs groupes
Avec Matplotlib
Appelez plt.scatter() une fois par groupe et définissez label= à chaque appel :
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=0)
groups = {
'Group A': (2, 3),
'Group B': (6, 6),
'Group C': (9, 2),
}
for name, (cx, cy) in groups.items():
x = rng.normal(loc=cx, scale=0.6, size=30)
y = rng.normal(loc=cy, scale=0.6, size=30)
plt.scatter(x, y, s=50, alpha=0.7, label=name)
plt.legend()
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Three Distinct Clusters')
plt.tight_layout()
plt.show()Chaque appel à scatter() choisit automatiquement la couleur suivante dans le cycle de couleurs par défaut de Matplotlib.
Avec Seaborn
Passez un DataFrame et utilisez hue= et éventuellement style= pour distinguer les groupes :
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=1)
rows = []
for group, (cx, cy) in [('A', (2, 3)), ('B', (6, 6)), ('C', (9, 2))]:
for _ in range(25):
rows.append({'x': rng.normal(cx, 0.6), 'y': rng.normal(cy, 0.6), 'group': group})
df = pd.DataFrame(rows)
sns.scatterplot(data=df, x='x', y='y', hue='group', style='group')
plt.title('Three Clusters — Seaborn Multi-Group')
plt.tight_layout()
plt.show()style='group' attribue une forme de marqueur distincte à chaque groupe en plus de la couleur, ce qui aide les lecteurs qui impriment en noir et blanc.
Nuages de points en apprentissage automatique
Les nuages de points ne servent pas uniquement à l'exploration — ils font partie intégrante du workflow ML.
1. Vérifier les relations linéaires avant la régression
Avant d'entraîner un modèle de régression linéaire, tracez les variables d'entrée par rapport à la cible. Un nuage approximativement linéaire indique que la régression linéaire est appropriée :
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=5)
house_size = rng.uniform(50, 300, 60) # square metres
house_price = 2000 * house_size + rng.normal(scale=40000, size=60) # EUR
plt.scatter(house_size, house_price, alpha=0.6, s=50)
plt.xlabel('House Size (m²)')
plt.ylabel('Price (EUR)')
plt.title('House Size vs Price — linear pattern suggests linear regression')
plt.tight_layout()
plt.show()Si le nuage montre une courbe plutôt qu'une droite, vous aurez peut-être besoin de caractéristiques polynomiales ou d'un modèle différent.
2. Visualiser les clusters après K-Means
Après avoir exécuté un algorithme de regroupement tel que k-means, colorez chaque point selon son étiquette de cluster pour confirmer la séparation :
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=8)
# Simulate cluster assignments from k-means
centers = [(1, 1), (5, 5), (9, 1)]
X, labels = [], []
for i, (cx, cy) in enumerate(centers):
X.extend(zip(rng.normal(cx, 0.7, 30), rng.normal(cy, 0.7, 30)))
labels.extend([i] * 30)
X = np.array(X)
labels = np.array(labels)
colors = ['tab:blue', 'tab:orange', 'tab:green']
for k in range(3):
mask = labels == k
plt.scatter(X[mask, 0], X[mask, 1], c=colors[k], s=50, alpha=0.7, label=f'Cluster {k}')
plt.legend()
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('K-Means Cluster Assignments')
plt.tight_layout()
plt.show()Des nuages bien séparés confirment que l'algorithme a trouvé des regroupements significatifs.
3. Évaluer les prédictions d'un modèle de régression
Tracez les valeurs réelles vs prédites après avoir entraîné un modèle. Un modèle parfait produit des points alignés sur la diagonale y = x :
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=2)
# Simulate actual and predicted values from a trained model
actual = rng.uniform(10, 100, 50)
predicted = actual + rng.normal(scale=8, size=50) # model with some noise
plt.scatter(actual, predicted, alpha=0.6, s=60, edgecolors='black', linewidths=0.5)
# Draw the ideal y = x line
lim = [min(actual.min(), predicted.min()) - 5, max(actual.max(), predicted.max()) + 5]
plt.plot(lim, lim, 'r--', linewidth=1.5, label='Perfect prediction')
plt.xlim(lim)
plt.ylim(lim)
plt.xlabel('Actual Values')
plt.ylabel('Predicted Values')
plt.title('Actual vs Predicted — regression model evaluation')
plt.legend()
plt.tight_layout()
plt.show()Des points répartis aléatoirement autour de la diagonale (sans courbure ni effet d'éventail systématique) indiquent que les erreurs du modèle sont non biaisées.
4. Visualiser la réduction de dimensionnalité (PCA / t-SNE)
Après avoir réduit des données de haute dimension à deux dimensions avec PCA ou t-SNE, un nuage de points est la façon naturelle d'afficher le résultat. Chaque point est une observation ; la couleur indique son étiquette de classe :
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=20)
# Simulate 2-D PCA output for three classes
class_data = {
'Class 0': ((-3, 0), 0.8),
'Class 1': ((0, 3), 0.8),
'Class 2': ((3, 0), 0.8),
}
for label, ((cx, cy), spread) in class_data.items():
x = rng.normal(cx, spread, 40)
y = rng.normal(cy, spread, 40)
plt.scatter(x, y, s=30, alpha=0.7, label=label)
plt.legend()
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.title('PCA Projection — 2D visualization of high-dimensional data')
plt.tight_layout()
plt.show()Des clusters qui se séparent nettement après réduction suggèrent que les classes sont réellement distinguables par les caractéristiques d'origine.
Enregistrer des nuages de points dans un fichier
Utilisez plt.savefig() avant plt.show() — appeler show() en premier efface la figure :
import matplotlib.pyplot as plt
import numpy as np
rng = np.random.default_rng(seed=99)
x = rng.random(50)
y = rng.random(50)
plt.scatter(x, y, alpha=0.7, s=60)
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Scatter Plot')
plt.tight_layout()
plt.savefig('scatter.png', dpi=150) # raster — good for web
plt.savefig('scatter.pdf') # vector — best for publications
plt.show()Utilisez dpi=300 pour des images PNG de qualité impression.
Quelle bibliothèque utiliser selon la situation
| Situation | Outil recommandé |
|---|---|
| Tracé rapide ponctuel avec des tableaux NumPy | matplotlib.pyplot.scatter() |
| Travail avec des DataFrames Pandas | seaborn.scatterplot() |
| Encodage couleur ou taille par point | matplotlib.pyplot.scatter() |
| Regroupement automatique par colonne | seaborn.scatterplot(hue=...) |
| Droite de régression intégrée | seaborn.regplot() |
| Personnalisation avancée de Matplotlib | fig, ax = plt.subplots() puis ax.scatter() |
Pour une exploration approfondie des paramètres de nuage de points Matplotlib — notamment les échelles logarithmiques, les annotations, les formes de marqueurs et la comparaison scatter() vs plot() — consultez le chapitre Nuages de points Matplotlib.
Erreurs courantes
Variable non définie. Chaque extrait de code de ce chapitre est autonome. Si vous combinez des extraits, assurez-vous que x et y sont définis dans le même script avant d'appeler plt.scatter().
Figure non effacée entre les tracés. Après plt.show(), Matplotlib efface la figure. Si vous exécutez des extraits dans un notebook Jupyter, chaque cellule crée automatiquement une nouvelle figure. Dans un script Python ordinaire, appelez plt.figure() pour démarrer un nouveau tracé si vous souhaitez plusieurs graphiques séparés.
Surcharge de points. Avec de nombreux points empilés les uns sur les autres, le graphique ressemble à une tache remplie. Réglez cela avec alpha=0.3 pour montrer la densité, ou passez à plt.hexbin() pour le binning en histogramme 2-D.
Pas de barre de couleur. Si vous passez un tableau à c, ajoutez toujours plt.colorbar() — sans elle, les lecteurs ne peuvent pas décoder l'échelle de couleurs.
Chapitres connexes
- Nuages de points Matplotlib — référence complète Matplotlib : axes logarithmiques, annotations, graphiques à bulles, couleurs de bordure,
scatter()vsplot() - Régression linéaire — ajuster et interpréter un modèle linéaire en Python
- Clustering K-Means — partitionner les données en groupes et les visualiser avec des nuages de points
- Distribution des données — comprendre la forme de vos données avant la modélisation
- Histogrammes Matplotlib — visualiser la distribution d'une seule variable
- Graphiques en courbes Matplotlib — tendances sur une variable ordonnée continue
- Découpage entraînement / test — diviser les données avant d'entraîner et d'évaluer les modèles