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.

Graphiques

Dans la foulée de premiers graphiques, nous approfondissons dans cette fiche la construction de graphiques avec Matplotlib pour visualiser des données. Nous regarderons successivement comment tracer des graphes de fonctions à une variable, des nuages de points avec barres d’erreur, des diagrammes en barre, et des histogrammes. Pour cela, nous nous appuierons sur la bibliothèque numpy. La table suivante résume les fonctionalités de Matplotlib que nous aurons parcourues.

Graphes de fonctions à une variable

On souhaite tracer le graphe de la fonction à une variable suivante:

parabole:{RRxx2.\text{parabole}: \begin{cases} \mathbb{R} & \rightarrow \mathbb{R}\\ x &\mapsto x^2 \end{cases} \,.

En Python, cette fonction s’écrit:

def parabole(x):
    return x**2

Graphes de fonctions avec des listes

Procédons d’abord au plus simple, comme dans la feuille précédente:

import matplotlib.pyplot as plt
%matplotlib widget
plt.ioff();
x_list = list(range(-5, 5))
y_list = [parabole(x) for x in x_list]

fig, ax = plt.subplots()
ax.plot(x_list, y_list)
fig.show()

C’est un peu décevant:

### BEGIN SOLUTION
x_list = [-5 + i * 0.1 for i in range(101)]
y_list = [parabole(x) for x in x_list]

fig, ax = plt.subplots()
ax.plot(x_list, y_list, label=r"$x \mapsto x^2$")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_title("Une parabole")
ax.legend()
### END SOLUTION
fig.show()

Graphes de fonctions avec numpy

Le tracé de graphes comme ci-dessus nous amène à manipuler de grands tableaux numériques. Aussi, pour plus de performance et de flexibilité, il est recommandé d’utiliser des tableaux numpy plutôt que des listes.

import numpy as np

Pour construire la liste des abscisses, on peut utiliser la fonction linspace, Elle est analogue à range, à part que l’on spécifie le nombre de points et non le pas et que la dernière valeur est incluse:

x = np.linspace(-5, 5, 11)
x

Pour construire la liste des ordonnées, on peut utiliser la vectorisation: lorsqu’on opération arithmétique est appliquée au tableau, elle est en fait appliquée à tous les éléments du tableau, et ce très rapidement.

y = parabole(x)
y

Le graphique se construit ensuite comme précédemment:

fig, ax = plt.subplots()
ax.plot(x, y)
fig.show()
### BEGIN SOLUTION
x = np.linspace(-5, 5, 100)
y = parabole(x)

fig, ax = plt.subplots()
ax.plot(x, y, label=r"$x \mapsto x^2$")
ax.set_xlabel("x")
ax.set_ylabel("y")
ax.set_title("Une parabole")
ax.legend()
### END SOLUTION
fig.show()

Effet de la discrétisation

Pour conclure sur les graphes de fonctions, nous observons l’effet de la discrétisation en traçant la fonction sinx\sin x entre π-\pi et π\pi, avec un nombre croissant de points:

import matplotlib.pyplot as plt
from numpy import pi, sin

xmin = -pi
xmax = pi
npoints = [2, 4, 8, 16, 32, 64, 128]

fig, ax = plt.subplots()

for n in npoints:
    x = np.linspace(xmin, xmax, n)
    y = sin(x)
    plt.plot(x, y, label=f"npoints: {n}")

ax.set_xlabel("x")
ax.set_ylabel("sin(x)")
ax.set_title("Discrétisation et sinus")
ax.legend(loc="lower right")
fig.show()

Tracé de mesures avec leurs incertitudes

La bibliothèque Matplotlib contient aussi une fonction errorbar pour tracer des mesures avec des barres d’erreur indiquant leurs incertitudes. Elle prend pour arguments principaux :

# Valeurs mesurées et incertitudes sur R
R = [12.05, 100.2, 998.7, 10987]
R_err = [r * 0.1 for r in R]

# Valeurs mesurées et incertitudes sur I
I = [0.45, 0.053, 0.0046, 4.7e-4]
I_err = [0.08, 0.013, 23e-4, 9e-5]

# Courbe théorique
U = 5.0
I_theo = [U / r for r in R]

# Visualisation
fig, ax = plt.subplots()
ax.errorbar(
    R,
    I,
    xerr=R_err,
    yerr=I_err,
    marker=".",
    color="r",
    linestyle="None",
    label="Mesures",
)
ax.plot(R, I_theo, color="b", label="Courbe théorique")
ax.set_title("Mesure de I(R)")
ax.set_xlabel("R [Ohms]")
ax.set_ylabel("I [A]")
ax.set_xscale("log")  # échelle logarithmique en x
ax.set_yscale("log")  # échelle logarithmique en y
ax.grid()
ax.legend()
fig.show()

Représentation en diagramme en barres ou circulaires

L’œil humain a une capacité naturelle à comparer les grandeurs visuelles (longueurs, surfaces, angles). Plusieurs types de graphiques, comme les diagramme en barres (ou en bâtons), ou circulaires (ou en camemberts), exploitent cette capacité pour comparer visuellement des quantités; par exemple pour comparer plusieurs catégories en absolu ou relatif, montrer l’évolution d’une même catégorie sur le temps ou repérer les tendances (hausse, baisse, stabilité). Pour dessiner de tels diagramme, les fonctions bar et pie -- les anglophones préfèrent les tartes aux camemberts -- prennent pour arguments principaux:

fruits = ["fraises", "abricots", "cerises", "myrtilles"]
weights = [4, 10, 3, 5.5]
colors = ["pink", "orange", "red", "blue"]

fig, (ax1, ax2) = plt.subplots(1, 2)

ax1.bar(fruits, weights, color=colors)
ax1.set_ylabel("kg")
ax1.set_title("Stocks de fruits")

ax2.pie(weights, labels=fruits, colors=colors)
ax2.set_title("Stocks relatifs de fruits")

fig.show()

Histogrammes

Un histogramme est un cas particulier de diagramme en barres qui prend en charge le regroupement des données en catégories. Pour en tracer un, la méthode hist admet pour arguments principaux:

notes = [
    8.5,
    12.5,
    11,
    10,
    13.5,
    5,
    18,
    16.5,
    12,
    13,
    11,
    9,
    10,
    4,
    20,
    12.5,
    10.5,
    7,
    8.5,
    13.5,
    15.5,
]

fig, ax = plt.subplots()
ax.hist(notes, bins=10)
ax.set_title("Notes interrogation")
ax.set_xlabel("Notes")
ax.set_ylabel("Nombre")
ax.grid()
fig.show()

ou avec des intervalles de 5 points:

bins = [0, 5, 10, 15, 20]  # intervalles

fig, ax = plt.subplots()
ax.hist(notes, bins=bins)
ax.set_title("Notes interro")
ax.set_xlabel("Notes")
ax.set_ylabel("Nombre")
ax.grid()
fig.show()
sequence = "ACGATCATAGCGAGCTACGTAGAA"

fig, ax = plt.subplots()
ax.hist(list(sequence))  # Noter la conversion en une liste de caractères
ax.set_xlabel("Bases")
ax.set_ylabel("Nombre")
ax.set_title(f"Distribution des bases\n dans la séquence {sequence}")
fig.show()

Bilan

Nous espèrons que ces courts exemples vous auront convaincu de l’utilité de la bibliothèque Matplotlib. Sachez qu’elle peut faire bien plus, y compris des graphiques en trois dimensions ou animés. Il existe par ailleurs d’autres outils pour produire des graphiques avec Python, par exemple directement à partir de tables Pandas, ou à l’aide de bibliothèques spécialisées comme Seaborn, bqplot, Bokeh ou Plotly. Ces trois dernières permettent de générer des graphiques interactifs, c’est-à-dire des graphiques dans lesquels on peut zoomer, se déplacer, changer les donnés au vol, etc. Nous vous invitons à les découvrir par vous-même.