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.
Remerciements
Cette fiche est fortement inspirée du chapitre Matplotlib de ce cours «Introduction à la programmation Python pour la biologie» (sources), ainsi que de la séance 4 de ce cours de L1 de Méthodes Numériques.
Graphes de fonctions à une variable¶
On souhaite tracer le graphe de la fonction à une variable suivante:
En Python, cette fonction s’écrit:
def parabole(x):
return x**2Graphes 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:
La courbe n’est pas lisse: on n’a en effet pas tracé stricto sensu le graphe de la fonction mathématique, mais une approximation de celui-ci par une ligne brisée. Il n’est en effet pas possible de représenter dans une machine des informations continues qui sont infinies. On dit que l’on a discrétisé le graphe la fonction.
Le graphe ne va que de -5 à +4.
La figure est pauvre en information (pas de noms sur les axes, de titre, de légende).
### 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 npPour 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)
xPour 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)
yLe 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 entre et , 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 :
xety: les abscisses et ordonnées des mesures (comme pourplot).xerretyerr(optionnels): les incertitudes respectives sur l’axe des abscisses et des ordonnées.
# 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:
x: les noms des catégories.y: les quantités pour chaque catégorie.color: les couleurs souhaitées pour les catégories.
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:
data: la série de données dont on veut représenter l’histogramme.bins(optionnel): pour des données numériques, les intervalles ou le nombre d’intervalles désirés.
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.