Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Premiers graphiques

«Un bon croquis vaut mieux qu’un long discours». Cela vaut aussi en analyse des données: la visualisation est un outil fondamental pour observer, explorer, synthétiser, comprendre les données et pour transmettre cette compréhension. Dans cette fiche, nous allons découvrir la bibliothèque matplotlib qui permet de réaliser en quelques lignes de jolis graphiques.

Visualisation de données par un nuage de points

Dans cet exemple -- purement fictif -- nous considérons des données mesurant l’évolution de la concentration d’un produit dans le sang (exprimé en mg/L) en fonction du temps (exprimé en heures):

Mesures

Temps (h)Concentration (mg/L)
13.5
25.8
39.1
411.8
617.5
721.3
83.2
926.8

Nous allons maintenant représenter l’évolution de la concentration en fonction du temps:

import matplotlib.pyplot as plt
%matplotlib widget
plt.ioff()

temps = [1, 2, 3, 4, 6, 7, 8, 9]
concentration = [5.5, 7.2, 11.8, 13.6, 19.1, 21.7, 3.2, 29.4]

fig, ax = plt.subplots()
ax.scatter(temps, concentration, marker="o", color="blue")
ax.grid()
ax.set_xlabel("Temps (h)")
ax.set_ylabel("Concentration (mg/L)")
ax.set_title("Concentration de produit en fonction du temps")
fig.show()

On appelle une telle figure un nuage de points. Chaque point représente une mesure: son abscisse indique le temps et son ordonnée la concentration mesurée. Par exemple, le premier point correspond à la mesure effectuée au bout d’une heure, où la concentration était de 5.5 mg/L.

Reprenons pas à pas ce code. Tout d’abord, on importe le sous-module pyplot de la bibliothèque Matplotlib et on lui donne l’alias plt pour l’utiliser plus commodément ensuite. Cet alias est standard, utilisez-le systématiquement. La commande %matplotlib widget permet d’avoir des figures interactives (possibilité de redimensioner, de zoomer, ...). La commande plt.ioff() permet de contrôler explicitement quand la figure est affichée.

import matplotlib.pyplot as plt
%matplotlib widget
plt.ioff()

On définit ensuite deux listes temps et concentration contenant les valeurs respectives du temps et de la concentration lors de chaque mesure. Ces deux listes doivent avoir la même longueur (sept éléments dans le cas présent):

temps = [1, 2, 3, 4, 6, 7, 8, 9]
concentration = [5.5, 7.2, 11.8, 13.6, 19.1, 21.7, 40.2, 29.4]

On crée une figure avec la fonction subplots() qui renvoie deux objets : une figure (fig) et un graphique (ax):

fig, ax = plt.subplots()

Pour le moment, la figure est vide:

fig

La méthode .scatter() permet de représenter un nuage de points sur le graphique. Les deux premiers arguments correspondent respectivement aux abscisses et aux ordonnées des points. Des arguments facultatifs sont ensuite précisés comme le symbole (marker) et la couleur (color).

ax.scatter(temps, concentration, marker="o", color="blue")
fig

La méthode .grid ajoute une grille de fond:

ax.grid()
fig

Les méthodes .set_xlabel() et .set_ylabel() définissent la légende des axes des abscisses et des ordonnées:

ax.set_xlabel("Temps (h)")
ax.set_ylabel("Concentration (mg/L)")
fig

La méthode .set_title() définit le titre du graphique:

ax.set_title("Concentration de produit en fonction du temps")
fig

Enfin la méthode .show() affiche la figure avec interactivité:

fig.show()
### BEGIN SOLUTION
ax.set_ylabel("Concentration (cg/L)")
### END SOLUTION
fig
assert "cg/L" in ax.yaxis.label._text, "La légende des ordonnées devrait contenir cg/L"
### BEGIN SOLUTION
temps = [1, 2, 3, 4, 6, 7, 9]
concentration = [5.5, 7.2, 11.8, 13.6, 19.1, 21.7, 29.4]

fig, ax = plt.subplots()
ax.scatter(temps, concentration, marker="o", color="blue")
ax.grid()
ax.set_xlabel("Temps (h)")
ax.set_ylabel("Concentration (cg/L)")
ax.set_title("Concentration de produit en fonction du temps")
### END SOLUTION
fig.show()
assert len(temps) == 7
assert len(concentration) == 7
assert 8 not in temps

assert ax.xaxis.label._text == "Temps (h)", "Légende des abscisses incorrecte"
assert ax.yaxis.label._text == "Concentration (cg/L)", (
    "Légende des ordonnées incorrecte"
)
assert ax.title._text == "Concentration de produit en fonction du temps", (
    "titre incorrect"
)

Visualisation d’une courbe

Revenons sur notre expérience. On suppose que l’évolution de la concentration du produit en fonction du temps peut-être modélisée par la fonction C(t)=2+3×tC(t) = 2 + 3 \times t exprimant la concentration en fonction du temps. Pour comparer ce modèle théorique avec nos données, nous allons compléter la figure précédente en y superposant un graphe de la fonction C(t)C(t) sous forme d’une courbe.

Pour cela, il suffit de définir la fonction C(t):

def C(t):
    return 2 + 3 * t

de calculer la concentration théorique à chaque pas de temps en utilisant une compréhension:

concentration_théorique = [C(t) for t in temps]

et d’utiliser la méthode .plot() pour construit une courbe -- en fait une ligne brisée -- à partir des coordonnées en abscisse et en ordonnées des points à représenter; les arguments facultatifs de spécifient le style de la ligne (linestyle) et sa couleur (color):

ax.plot(temps, concentration_théorique, color="green", linestyle="--")
fig.show()

La cellule suivante résume la construction complète de la figure, en ajoutant une légende et en modifiant l’étendue des axes des abscisses et des ordonnées:

import numpy as np
import matplotlib.pyplot as plt

temps = [1, 2, 3, 4, 6, 7, 9]
concentration = [5.5, 7.2, 11.8, 13.6, 19.1, 21.7, 29.4]


def C(t):
    return 2 + 3 * t


concentration_théorique = [C(t) for t in temps]

fig, ax = plt.subplots()

ax.scatter(temps, concentration, marker="o", color="blue", label="mesures")
ax.plot(temps, concentration_théorique, color="green", linestyle="--", label="modèle")

ax.set_xlim(0, 10)  # Étendue de l'axe des x
ax.set_ylim(0, 35)
ax.grid()

ax.set_xlabel("Temps (h)")
ax.set_ylabel("Concentration (g/L)")
ax.set_title("Concentration de produit en fonction du temps")
ax.legend(loc="upper left")

fig.show()

Nous enregistrons maintenant la figure (méthode savefig) sous la forme d’une image au format svg. Les arguments optionnels configurent les marges autour du graphique (bbox_inches) ainsi que la résolution de l’image (dpi):

fig.savefig("media/concentration_vs_temps.svg", bbox_inches="tight", dpi=200)

Vous pouvez maintenant retrouver la figure dans le fichier media/concentration_vs_temps.svg.

Bilan

Dans cette fiche, nous avons vu comment construire un graphique, avec un nuage de points (scatter) et une courbe (plot) représentant respectivement des données de mesures et un modèle théorique. Nous avons aussi vu comment enrichir ce graphique en configurant les axes (set_xlim, set_ylim, set_xlabel, set_ylabel), choisissant le style (grid, marker, color, ls) et ajoutant une légende et un titre (set_title).

import matplotlib.pyplot as plt

temps = [1, 2, 3, 4, 6, 7, 8, 9]
concentration = [5.5, 7.2, 11.8, 13.6, 19.1, 21.7, 40.2, 29.4]

plt.figure()
plt.scatter(temps, concentration, marker="o", color="blue")
plt.grid()
plt.xlabel("Temps (h)")
plt.ylabel("Concentration (mg/L)")
plt.title("Concentration de produit en fonction du temps");