Définition
Un script Python qui traite des données finit presque toujours par produire une liste de nombres : des ventes mois par mois, des résultats de calcul. Lue telle quelle dans un terminal, cette liste ne montre ni tendance ni pic ; il faut un dessin pour que l'œil fasse ce que le texte ne peut pas faire.
matplotlib est la bibliothèque qui répond à ce besoin. Elle transforme des nombres en courbes, en barres, en histogrammes ou en nuages de points, affichés dans une fenêtre ou enregistrés en image, au format PNG, SVG ou PDF. Elle ne fait pas partie de la bibliothèque standard : le premier import lève une ModuleNotFoundError tant qu'elle n'a pas été installée avec pip, de préférence dans un environnement virtuel.
pip install matplotlibUne fois l'installation faite, le code minimal tient en quelques lignes. L'alias plt, posé avec le mot-clé as, est une convention si répandue que la documentation officielle et la quasi-totalité des exemples en ligne la supposent acquise.
import matplotlib.pyplot as plt
mois = ["janvier", "février", "mars"]
ventes = [120, 180, 150]
plt.plot(mois, ventes)
plt.savefig("ventes.png")Reste une question naturelle : quelles données accepte-t-il ? La réponse est rassurante : de simples listes de nombres suffisent. Les tableaux numpy et les colonnes de pandas passent tout aussi bien, mais rien ne les impose. Un axe temporel se construit à partir d'objets datetime, que matplotlib sait afficher sans conversion préalable en texte.
Ce qu'il remplace
La question qui compte n'est pas ce que matplotlib sait faire, mais ce qu'on faisait avant lui. Avant, il fallait exporter un fichier CSV, l'ouvrir dans un tableur, sélectionner deux colonnes et insérer un graphique. Cette méthode fonctionne très bien, une fois.
Le problème apparaît au deuxième passage. Les données du mois suivant arrivent, et tout est à refaire : la sélection, les couleurs, le titre, l'échelle. matplotlib ne produit pas de plus belles figures qu'un tableur, et avec ses réglages par défaut il en produit même de moins belles. Ce qu'il apporte est différent : des figures reproductibles, qui redonnent exactement la même mise en forme au prochain lancement, sans un seul clic. C'est cette garantie qui justifie de l'apprendre, pas l'esthétique.
Encore faut-il savoir quand s'en servir. Le tableau suivant compare les cas les plus courants et l'outil qui leur correspond.
| Situation | L'outil adapté |
|---|---|
| Trois chiffres à montrer une seule fois | Un tableur, bien plus rapide |
| Figure à régénérer à chaque nouvelle version des données | matplotlib |
| Coup d'oeil rapide sur un tableau déjà chargé | La méthode plot de pandas |
| Graphique survolable dans une page web | Une bibliothèque interactive comme Plotly |
| Figures statistiques au style soigné | seaborn, qui s'appuie dessus |
Les deux façons d'écrire
C'est la première source de confusion, et elle n'a rien à voir avec les graphiques. matplotlib s'écrit de deux manières, et les exemples trouvés en ligne mélangent les deux sans jamais le signaler.
Le style implicite passe par plt, qui retient la figure courante : chaque appel s'applique au dernier graphique commencé. Le style explicite fait l'inverse, il nomme la figure et ses axes puis travaille directement sur ces objets.
# Style implicite : plt retient la figure courante
plt.plot(x, y)
plt.title("Ventes")
plt.xlabel("Mois")
# Style explicite : la figure et les axes sont nommés
fig, ax = plt.subplots()
ax.plot(x, y)
ax.set_title("Ventes")
ax.set_xlabel("Mois")Un détail change en cours de route : title devient set_title. Coller une ligne d'un tutoriel dans du code écrit dans l'autre style donne alors une AttributeError déroutante, puisque les deux lignes viennent de la même bibliothèque. Comment choisir entre les deux, alors ? Le style implicite convient à une figure unique et jetable. Dès qu'il y a deux graphiques côte à côte, ou une figure construite à l'intérieur d'une fonction, le style explicite devient le seul tenable : la notion de figure courante perd tout son sens dès que plusieurs figures coexistent.
L'erreur classique
Le piège le plus fréquent est une question d'ordre : plt.show() vide la figure une fois la fenêtre refermée. Enregistrer l'image après l'avoir affichée écrit donc un fichier parfaitement blanc, sans le moindre message d'erreur.
# Image blanche, et aucune erreur
plt.plot(x, y)
plt.show()
plt.savefig("courbe.png")
# L'ordre correct
plt.plot(x, y)
plt.savefig("courbe.png")
plt.show()Un second piège se cache dans une boucle, plus discret car il ne provoque pas non plus d'erreur.
Sans figure neuve à chaque tour de boucle, les courbes s'empilent toutes sur le même graphique : la dixième image générée contient en réalité dix séries superposées. Sur un script qui produit des centaines de fichiers d'un coup, cette accumulation finit par saturer la mémoire disponible.
La correction est simple une fois le problème repéré : un plt.figure() au début du tour, ou un plt.close() à la fin, remet les compteurs à zéro avant chaque nouvelle image.
Questions fréquentes
Pourquoi rien ne s'affiche quand je lance mon script ?
Soit l'appel à plt.show() manque à la fin du fichier, soit le programme s'exécute là où aucune fenêtre ne peut s'ouvrir, sur un serveur ou dans un conteneur. Dans ce second cas il n'y a rien à réparer : la figure doit être enregistrée avec savefig au lieu d'être affichée.
Faut-il apprendre matplotlib ou seaborn ?
seaborn est construit au-dessus et ne le remplace pas. Il produit en une ligne une figure déjà présentable, mais le moindre réglage ensuite, déplacer une légende, changer une échelle, régler un axe de dates, repasse par les objets de matplotlib. Apprendre seaborn seul mène droit au blocage.
Peut-on tracer directement depuis un tableau pandas ?
Oui, df.plot() appelle matplotlib en dessous et renvoie l'objet axes. Toutes les commandes vues plus haut restent donc valables sur ce résultat, ce qui en fait le chemin le plus court entre un fichier de données brut et une figure lisible.