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.
Commandes et options essentielles de la bibliothèque Matplotlib
import matplotlib.pyplot as plt: import de la bibliothèque.%matplotlib widget: permet l’affichage de figure interactives.plt.ioff(): évite l’affichage implicite de figure.fig, ax = plt.subplots(): construction d’une figure.ax.scatter(x, y, **options): dessin d’un nuage de points.ax.plot(x, y, **options): dessin d’une ligne brisée.ax.errorbar(x, y, **options): dessin d’un nuage de points avec barres d’erreur.ax.bar(x, y, **options): dessin d’un diagramme en barres.ax.hist(data, bins=4, **options): dessin d’un histogramme.ax.set_xlim(xmin, xmax): limite l’axe des abscisses entre les valeursxminetxmax.ax.set_ylim(ymin, ymax): limite l’axe des ordonnées entre les valeursyminetymax.ax.set_xscale('log'): axe des abscisses en échelle logarithmique.ax.set_yscale('log'): axe des ordonnées en échelle logarithmique.ax.set_xlabel('texte'): donne un titre à l’axe des abscisses.ax.set_ylabel('texte'): donne un titre à l’axe des ordonnées.ax.set_title('texte'): définit le titre du graphique.ax.grid(): dessin d’une grille de fond.ax.legend(): ajout d’une légende en se basant sur les optionslabeldescatter,plot, etc.fig.show(): affiche la figure interactive.
Options:
color: définit la couleur des points ou de la courbe; à choisir parmi “green”, “blue”, “red”, “black”, etc, ou “g”, “b”, “r”, “k”, etc.linestyle: définit le style du trait: “-” (trait continu), “–” (tireté), “:” (pointillé) ou “None” (aucun trait).marker: définit le style des points: “.” (point), “o” (rond), “*” (étoile), “d” (diamant), etc.label: donne un nom au tracé pour construire une légende par la suite.
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 ** 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:
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).
Exercice
Améliorez ci-dessous le graphe ci-dessus:
Augmentez le nombre de points.
Indication: utilisez une compréhension pour construire la listex_listcontenant[-5, -4.9, -4.8, ..., 4.9, 5].Assurez vous que le graphe aille de -5 à +5.
Nommez les axes et ajoutez un titre et une légende.
Indication: consultez le rappel des commandes essentielles ci-dessus, ainsi que les exemples de la fiche premiers graphiques.
### BEGIN SOLUTION
x_list = [-5 + i * .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
array([-5., -4., -3., -2., -1., 0., 1., 2., 3., 4., 5.])
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
array([25., 16., 9., 4., 1., 0., 1., 4., 9., 16., 25.])
Attention
Les notations ci-dessus sont traditionnelles mais peuvent porter à confusion:
l’instruction y = parabole(x) ne calcule pas l’ordonnée \(y\) d’un point d’abscisse \(x\)
mais toutes les ordonnées d’un coup de tous les points dont les abscisses sont données
dans le tableau x.
Le graphique se construit ensuite comme précédemment:
fig, ax = plt.subplots()
ax.plot(x, y)
fig.show()
Exercice
Reproduisez, en utilisant des tableaux numpy comme ci-dessus, la figure améliorée de
l’exercice précédent.
### 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 \(\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 :
xety: les abscisses et ordonnées des mesures (comme pourplot).xerretyerr(optionnels): les incertitudes respectives sur l’axe des abscisses et des ordonnées.
Exemple
On souhaite visualiser des mesures d’un courant \(I\) traversant une résistance \(R\) alimentée par une tension \(U=5\) V à ses bornes, pour différentes valeurs de \(R\) mesurées à l’ohmètre (dont la notice indique une incertitude de \(10\%\)) et les comparer à une courbe théorique.
# 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.
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.
Exemple
Le diagramme suivant représente l’état des stocks de quelques fruits chez un commerçant, en absolu (diagramme en barre) et en relatif (diagramme circulaire).
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.
Exemple
Nous traçons un histogramme pour des notes à une interrogation, avec dix intervalles déterminés automatiquement:
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()
Exemple
Nous traçons maintenant un histogramme pour des données non numériques: la distribution des bases “A”, “C”, “G”, “T” dans une séquence d’ADN.
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.
Voir aussi
Le site de Matplotlib fournit de nombreux exemples détaillés, n’hésitez pas à le consulter.
Le site Python Graph Gallery propose aussi des exemples de code pour différents types de graphiques, réalisés avec Matplotlib ou d’autres bibliothèques.
Enfin, des cheat sheets de Matplotlib sont extrêmement utiles et très bien faites.