W3docs

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

MotifSignification
Les points montent de gauche à droiteCorrélation positive — quand X augmente, Y tend à augmenter
Les points descendent de gauche à droiteCorrélation négative — quand X augmente, Y tend à diminuer
Aucune forme discernableAucune corrélation linéaire entre les variables
Bande étroite et serréeCorrélation forte
Nuage large et diffusCorrélation faible
Points éloignés du nuage principalValeurs 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 numpy

Exemple 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 tableau
  • alpha — 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 pandas

Nuage 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

SituationOutil recommandé
Tracé rapide ponctuel avec des tableaux NumPymatplotlib.pyplot.scatter()
Travail avec des DataFrames Pandasseaborn.scatterplot()
Encodage couleur ou taille par pointmatplotlib.pyplot.scatter()
Regroupement automatique par colonneseaborn.scatterplot(hue=...)
Droite de régression intégréeseaborn.regplot()
Personnalisation avancée de Matplotlibfig, 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

Was this page helpful?