HOWTO · Matplotlib
Comment créer un tracé de surface dans Matplotlib
Nous pouvons créer un tracé de surface dans Matplotlib en utilisant la méthode plot_surface().
Sur cette page
Pour créer un tracé de surface 3D avec Matplotlib, préparez des tableaux bidimensionnels X, Y et Z compatibles, créez un axe avec projection="3d", puis transmettez ces tableaux à Axes3D.plot_surface. L’exemple ci-dessous construit une grille de coordonnées à partir d’une fonction mathématique, ajoute des libellés aux axes, une barre de couleurs et enregistre la figure. Cette méthode convient aussi à des mesures lorsque leurs coordonnées et leurs hauteurs peuvent être représentées sur une grille rectangulaire.
Préparer votre environnement
Installez NumPy pour manipuler les tableaux et les grilles, et Matplotlib pour créer les graphiques. Dans un terminal, exécutez python -m pip install numpy matplotlib dans l’environnement Python que vous comptez utiliser. Si vous gérez déjà vos paquets dans un environnement ou un notebook, installez les deux bibliothèques à cet endroit afin qu’elles soient disponibles pour l’interpréteur qui exécutera votre script.
L’exemple importe NumPy et matplotlib.pyplot. Les fonctions de tracé 3D sont incluses dans Matplotlib ; projection="3d" crée un axe 3D, sans qu’il soit nécessaire d’importer séparément Axes3D. La méthode utilisée sur cet axe est Axes3D.plot_surface.
Préparer vos données
Un tracé de surface associe une hauteur à chaque emplacement d’un plan défini par deux coordonnées. Pour des coordonnées régulièrement espacées, np.linspace() crée des valeurs de coordonnées unidimensionnelles et np.meshgrid() les développe en grilles bidimensionnelles X et Y. Calculez Z à partir de ces grilles ou fournissez des hauteurs mesurées disposées aux mêmes emplacements.
Les trois tableaux doivent avoir des formes compatibles : chaque Z[i, j] représente la hauteur au point de coordonnées X[i, j] et Y[i, j]. Les versions actuelles de Matplotlib acceptent aussi des vecteurs de coordonnées unidimensionnels x et y et les développent face à un Z bidimensionnel, mais le tableau des hauteurs lui-même doit toujours correspondre aux dimensions de la grille : un Z calculé sur une grille différente de X et Y déclenche une ValueError, comme le montre la section de dépannage ci-dessous avec une exécution réelle. Commencez par construire les grilles de coordonnées, puis calculez ou remodelez les hauteurs sur ces mêmes grilles. Si les mesures dispersées ne forment pas une grille rectangulaire, préparez ou interpolez les données sur une grille avant d’utiliser plot_surface.
Créer le tracé de surface
Cet exemple complet utilise la fonction radiale régulière sin(sqrt(x² + y²)). Il crée les grilles, trace la surface, ajoute des libellés aux trois axes, affiche une échelle de couleurs et enregistre le résultat sous surface-plot.png dans le répertoire courant. Exécutez-le dans un environnement où NumPy et Matplotlib sont installés. L’exemple n’affiche aucun texte dans la console ; il produit une image enregistrée et une fenêtre Matplotlib si le moteur graphique actif permet l’affichage. Les libellés visibles des axes, du titre et de la barre de couleurs restent en anglais, car le code de l’exemple est conservé à l’identique.
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))
fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
surface = ax.plot_surface(X, Y, Z, cmap="viridis")
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.set_title("Surface Plot")
fig.colorbar(surface, ax=ax, label="Z value")
fig.savefig("surface-plot.png", dpi=150, bbox_inches="tight")
plt.show()
Comme ce script n’affiche aucun texte, il n’y a pas de bloc de sortie console. La barre de couleurs associe les couleurs de la surface à leurs valeurs ; la grille définit la géométrie, tandis que la palette détermine son apparence. Dans un notebook, l’environnement de tracé affiche généralement la figure ; dans un script, plt.show() demande au moteur Matplotlib configuré de l’afficher.
Personnaliser votre tracé de surface
L’exemple ci-dessous applique les personnalisations les plus courantes à la même surface. Il remplace la palette par plasma, supprime les arêtes du maillage et fait pivoter la caméra vers une élévation et un azimut fixes avant d’ajouter la barre de couleurs et d’enregistrer la figure sous customized-surface-plot.png.
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))
fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
surface = ax.plot_surface(X, Y, Z, cmap="plasma", edgecolor="none")
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.set_title("Customized Surface Plot")
ax.view_init(elev=30, azim=45)
fig.colorbar(surface, ax=ax, label="Z value")
fig.savefig("customized-surface-plot.png", dpi=150, bbox_inches="tight")
plt.show()
Choisissez une palette qui rende les variations de Z faciles à lire. Dans cet exemple, cmap="plasma" remplace la progression viridis du premier exemple, et la barre de couleurs aide à interpréter cette correspondance. L’option edgecolor="none" supprime les arêtes dessinées du maillage, qui peuvent distraire d’une surface continue sur une grille dense ; conservez les arêtes par défaut lorsque la grille d’échantillonnage elle-même doit rester visible.
Pour modifier la caméra, appelez ax.view_init(elev=30, azim=45) avant d’enregistrer ou d’afficher la figure. elev règle l’élévation de la vue et azim fait pivoter celle-ci autour de l’axe vertical. Ajustez ces valeurs jusqu’à ce que la forme et les axes soient bien visibles ; l’angle adapté dépend des données et de ce que vous souhaitez montrer. Par rapport à la première figure, la caméra pivotée de la seconde figure expose davantage le versant éloigné du pic central.
Pour une grille dense, plot_surface accepte des paramètres d’échantillonnage des lignes et des colonnes, comme rcount et ccount. Des valeurs plus faibles tracent moins de lignes et de colonnes échantillonnées et peuvent accélérer le rendu d’une grande surface, au prix d’une perte de détails visibles. Conservez suffisamment d’échantillons pour représenter les variations importantes des données. Enregistrez une image à partager avec fig.savefig("surface-plot.png", dpi=150, bbox_inches="tight") ; appelez cette méthode avant plt.show() pour rester compatible avec les moteurs d’affichage qui ferment la figure après l’avoir montrée. Choisissez un autre nom ou répertoire si vous souhaitez conserver plusieurs versions.
Comparer avec un tracé en fil de fer
Un tracé en fil de fer ne dessine que les lignes de la grille de la même surface, sans faces remplies ni palette de couleurs. Axes3D.plot_wireframe accepte les mêmes grilles X, Y et Z, vous pouvez donc passer d’une vue à l’autre sans préparer de nouvelles données. Le fil de fer est utile lorsque la structure de la grille elle-même compte, lorsqu’une surface remplie masquerait le côté éloigné de la forme, ou comme vérification structurelle rapide de données inconnues avant de produire un rendu de surface complet.
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 50)
y = np.linspace(-5, 5, 50)
X, Y = np.meshgrid(x, y)
Z = np.sin(np.sqrt(X**2 + Y**2))
fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
ax.plot_wireframe(X, Y, Z, rstride=2, cstride=2, color="tab:blue")
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.set_title("Wireframe Plot")
fig.savefig("wireframe-plot.png", dpi=150, bbox_inches="tight")
plt.show()
Les arguments rstride et cstride sautent des lignes et des colonnes pour que les lignes restent lisibles ; l’exemple trace une ligne et une colonne sur deux d’une grille de 50 par 50. Contrairement à plot_surface, un fil de fer n’a pas de couleurs de faces, il n’y a donc rien qu’une barre de couleurs puisse expliquer. Pour une présentation finale, la surface remplie communique généralement mieux les différences de hauteur, tandis que le fil de fer montre plus clairement comment la grille elle-même est échantillonnée.
Corriger une erreur de formes incompatibles
L’échec le plus fréquent de plot_surface est un tableau Z dont la forme ne correspond pas aux grilles de coordonnées. Le script ci-dessous calcule Z sur une grille de 50 par 50, mais le transmet avec les grilles X et Y de 100 par 100 :
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
x_small = np.linspace(-5, 5, 50)
y_small = np.linspace(-5, 5, 50)
X_small, Y_small = np.meshgrid(x_small, y_small)
Z = np.sin(np.sqrt(X_small**2 + Y_small**2))
fig = plt.figure()
ax = fig.add_subplot(111, projection="3d")
ax.plot_surface(X, Y, Z, cmap="viridis")
plt.show()
L’exécution du script s’arrête à l’appel de plot_surface avec cette erreur :
ValueError: shape mismatch: objects cannot be broadcast to a single shape. Mismatch is between arg 0 with shape (100, 100) and arg 2 with shape (50, 50).
Pour la corriger, calculez Z à partir des mêmes grilles que vous transmettez à plot_surface, comme le fait le premier exemple, de sorte que Z.shape soit égal à X.shape et à Y.shape. En cas de doute, affichez les trois formes avant de tracer et comparez-les : chaque entrée de Z a besoin d’exactement une paire de coordonnées, ni plus ni moins.
Conclusion
Les étapes essentielles consistent à créer des grilles de coordonnées, à faire correspondre Z à ces grilles, à ajouter un axe 3D, puis à appeler Axes3D.plot_surface. Une palette et une barre de couleurs expliquent les valeurs de hauteur, tandis que les réglages de vue et d’échantillonnage aident à présenter clairement la forme. Lorsque vous devez inspecter la grille elle-même, plot_wireframe trace les mêmes données sous forme de lignes. Enregistrez la figure si vous avez besoin d’un fichier image et adaptez la résolution de la grille ou l’angle de vue aux données représentées.
Foire aux questions
-
Quelles données puis-je utiliser pour un tracé de surface ?
Utilisez des valeurs définies selon deux coordonnées, chaque hauteur correspondant à un emplacement d’une grille rectangulaire. Une fonction est pratique pour une démonstration ; les mesures conviennent si elles sont organisées sur des grilles de coordonnées compatibles. Les points dispersés doivent d’abord être convertis en grille. -
Comment installer les bibliothèques nécessaires ?
Installez NumPy et Matplotlib dans l’environnement qui exécute votre script avecpython -m pip install numpy matplotlib. -
Puis-je modifier les couleurs de la surface ?
Oui. Définissez l’argumentcmapdeplot_surface, puis ajoutez une barre de couleurs avecfig.colorbar(surface, ax=ax)pour montrer la correspondance entre les couleurs et les valeurs. -
Comment modifier l’angle de vue ?
Utilisezax.view_init(elev=..., azim=...). L’élévation modifie la hauteur du point de vue, et l’azimut sa rotation autour du graphique. -
Pourquoi
X,YetZdoivent-ils avoir des formes compatibles ?
Matplotlib a besoin d’une paire de coordonnées et d’une hauteur pour chaque emplacement de la grille. SiZa été calculé sur une autre grille,plot_surfacedéclenche uneValueErrorconcernant des formes qui ne peuvent pas être diffusées ensemble. Créez les grilles de coordonnées avecnp.meshgrid()et calculezZà partir de ces mêmes grilles afin que les entrées correspondantes s’alignent.