Introduction à matplotlib

Tracer un graphe à partir d'une liste de points

L'exemple suivant va nous permettre de nous familiariser avec les fonctionnalités de base pyplot un module du package matplotlib.

Documentation officielle : https://matplotlib.org/3.0.2/tutorials/index.html
Pour les initiés, la liste des fonctions liées à pyplot : https://matplotlib.org/api/pyplot_summary.html

In [1]:
#-*- coding: utf-8 -*-
#on crée un alias plt au module matplotlib importé
import matplotlib.pyplot as plt     
#afficher les graphes dans le notebook
%matplotlib inline
import numpy as np
In [2]:
Z = [k for k in range(1,19)]
# Les rayons sont en nanomètre
R = [0.032, 0.031, 0.123, 0.089, 0.082, 0.077, 
     0.075, 0.073, 0.072, 0.071, 0.154, 0.136, 
     0.118, 0.111, 0.106, 0.102, 0.099, 0.098]
plt.plot(Z,R,'go-',markersize=10)
plt.grid()
plt.show()
  • plot(x, y): permet de tracer des couples de points reliés par des segments. x et y doivent être contenus dans des tableaux de même taille. Cette fonctions admet une multitude d'options, vous trouverez de nombreux exemples dans la documentation officielle : http://matplotlib.org/
    Extrait de la doc officielle:
    Plot lines and/or markers to the Axes. args is a variable length argument, allowing for multiple x, y pairs with an optional format string. For example, each of the following is legal:
    • plot(x, y) : plot x and y using default line style and color
    • plot(x, y, 'bo') : plot x and y using blue circle markers
    • plot(y) : plot y using x as index array 0..N-1
    • plot(y, 'r+') ; ditto, but with red plusses
  • grid(): permet d'afficher une grille.
  • show() : déclenche l’affichage à l’écran et stoppe le script. La fenêtre d’affichage propose un mode interactif permettant par exemple de zoomer sur une partie de la figure.
  • savefig(nom_fichier) : permet de sauvegarder la figure en cours. Le nom de fichier doit être du type str donc entre quotes ou guillemets.
  • xlabel(titre) et ylabel(titre) : permettent d’ajouter des titres à vos axes
  • title(titre) : ajoute un titre à votre graphique

Plusieurs graphes sur le même graphique

In [3]:
M = [1, 4, 6.9, 9, 10.8, 12, 14, 16, 19, 20.2, 
     23, 24.3, 27, 28.1, 31, 32.1, 35.5, 39.9]

plt.plot(Z,R,'ro-',markersize=10)
plt.grid()
plt.ylabel(u"Rayon atomique (nm)")
plt.xlabel(u"Numéro atomique")

plt.twinx ()
plt.plot(Z,M,'go-',markersize=10)
plt.ylabel(u"Masse molaire (g/mol)")

plt.show()

Des légendes liées aux graphes

In [4]:
plt.plot(Z,R,'ro-',markersize=10, label="R")

plt.ylabel(u"Rayon atomique (nm)")
plt.xlabel(u"Numéro atomique")
plt.legend(loc='upper left')
plt.grid()

plt.twinx ()
plt.plot(Z,M,'go-',markersize=10, label="M")
plt.ylabel(u"Masse molaire (g/mol)")
plt.legend(loc='lower right')

plt.show()

Plusieurs graphiques différents

In [5]:
plt.figure(figsize=(20,6))
plt.subplot(121) 
plt.plot(Z,R,'ro-',markersize=10)
plt.grid()
plt.ylabel(u"Rayon atomique (nm)")
plt.xlabel(u"Numéro atomique")
plt.title(u"Taille d'un atome en fonction de sa position dans\n la classification périodique")
plt.subplot(122) 
plt.plot(Z,M,'go',markersize=10)
plt.grid()
plt.ylabel(u"Masse molaire (g/mol)")
plt.xlabel(u"Numéro atomique")
plt.title(u"\nMasse en fonction du nombre de proton")
plt.show()
  • subplot(mnp) : divise la fenêtre graphique courante en une matrice m x n matrice de sous fenêtres et sélectionne la p-ième sous-fenêtre comme emplacement de dessin par défaut.

Les axes

Modification des graduations principales sur les axes

In [6]:
plt.figure(figsize=(20,6))
plt.subplot(121) 
# Début des modifications sur les axes
x_min, x_max = min(Z), max(Z)
plt.xticks(np.linspace(x_min, x_max, len(Z), endpoint=True))

plt.ylim(0.02, 0.2)
plt.yticks(np.linspace(0.02, 0.2, 19, endpoint=True))
# Fin
# Autre exemple de style de ligne et de point
plt.plot(Z,R,'ro:', markersize=15, 
                    linewidth=2,
                    markerfacecolor='yellow',
                    markeredgecolor='gray')
plt.grid()
plt.ylabel(u"Rayon atomique (nm)")
plt.xlabel(u"Numéro atomique")
plt.title(u"Taille d'un atome en fonction de sa position dans\n la classification périodique")
plt.subplot(122)
# Début des modifications sur les axes
plt.xticks(np.linspace(x_min, x_max, len(Z), endpoint=True))

plt.ylim(0.02, 0.2)
plt.yticks(np.linspace(0, 40, 9, endpoint=True))
# Fin
# Autre exemple de style de ligne et de point
plt.plot(Z,M,'gp',markersize=12, markerfacecolor='white')
plt.grid()
plt.ylabel(u"Masse molaire (g/mol)")
plt.xlabel(u"Numéro atomique")
plt.title(u"\nMasse en fonction du nombre de proton")
plt.show()
  • xlim : fixe les valeurs limites sur l'axe des abscisses
  • ylim : fixe les valeurs limites sur l'axe des ordonnées
  • xticks : fixe les valeurs des graduations principales (majeures) sur les abscisses
  • yticks : fixe les valeurs des graduations principales (majeures) sur les ordonnées

Ci-dessous la documentation officielle pour ceux qui veulent en savoir plus.

Et les graduations secondaires (mineures)

Un exemple avec la partie entière

In [7]:
def partiEntiere(x):
    """
    x -> list
    """
    y = []
    for i in x:
        if i < 0 :
            y.append(int(i-1))
        else:
            y.append(int(i))
    return y
In [8]:
plt.figure(figsize=(12,6))

x = np.linspace(-3, 3, 100)
y = partiEntiere(x)

# on ajoute les graduations secondaires
plt.minorticks_on()
# paramétrage du style des graduations principales et secondaires
plt.tick_params(which='major', length=10, width=2, direction='inout', grid_linestyle="-", grid_color = "b")
plt.tick_params(which='minor', length= 5, width=2, direction='in',    grid_linestyle="--", grid_color = "g")
plt.grid(which="both")
# les valeurs des graduations principales
min_x, max_x = min(x), max(x)
min_y, max_y = min(y), max(y)

plt.xlim(min_x, max_x)
plt.xticks(np.linspace(min_x, max_x, int(max_x-min_x+1), endpoint = True))

plt.ylim(min_y, max_y)
plt.yticks(np.linspace(min_y, max_y, int(max_y-min_y+1), endpoint = True))

plt.plot(x, y, ".r")
plt.title("Partie entière")
plt.xlabel("x")
plt.ylabel("y")

plt.show()

Position des axes

Jusqu'à maintenant les axes se trouvaient sur les bords du graphique, mais ils peuvent être placés de manière arbitraire. Commençons par nous débarasser de ceux qui se trouvent en haut et à droite en supprimant la couleur

Comme nous pouvons le lire dans la doc ci-dessous la modification des axes est accessible à l'aide de la fonction $spines$.

Pour utiliser cette fonction nous avons besoin de récupérer la configuration des axes par défaut de notre figure

In [ ]:
ax = plt.axes()

Il ne reste plus qu'à modifier les axes

In [ ]:
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')

Pour les deux axes restant nous allons les placer au centre du graphique en suivant les informations de la documentation :

Spine position is specified by a 2 tuple of (position type, amount). The position types are:

  • 'outward' : place the spine out from the data area by the specified number of points. (Negative values specify placing the spine inward.)
  • 'axes' : place the spine at the specified Axes coordinate (from 0.0-1.0).
  • 'data' : place the spine at the specified data coordinate.

Nous ajoutons également une légende pour bien distinguer les deux fonctions. Dans cette légende il est possible d'avoir recours à $\LaTeX$ pour la mise en forme mathématique. Dans ce cas les balises $\LaTeX$ doivent être encadrées par deux symboles $

http://docs.wixstatic.com/ugd/bf8f20_557167febde14efb9d7844776396beb1.pdf" : liste des balises $\LaTeX$ de base pour les mathématiques

In [9]:
# Quelques propriétés du graphique
plt.figure(figsize = (8,5), dpi=80)
ax                 = plt.axes()

# Intervalle de définition et fonctions
x                  = np.linspace(-np.pi, np.pi, 100)
cosinus, sinus     = np.cos(x), np.sin(x)

# Paramétrage des axes
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_position(('data',0))
ax.spines['left'].set_position(('data',0))

plt.plot(x, cosinus, label='$f_1:x \mapsto \cos(x)$')
plt.plot(x, sinus, label='$f_2:x \mapsto \sin(x)$')

# Légendes
plt.legend()
# Affichage
plt.show()

Flécher les axes

Quand les graduations des axes ne sont pas utiles, nous pouvons utiliser l'instruction suivante

In [ ]:
plt.axis('off')

Il ne reste plus qu'à dessiner des flèches en guise d'axes

In [10]:
# Quelques propriétés du graphique
plt.figure(figsize = (8,5), dpi=80)
ax                 = plt.axes()

# La fonction sinus sur un intervalle de définition 
x                  = np.linspace(-np.pi, np.pi, 100)
sinus              = np.sin(x)

# Paramétrage des axes fléchés, sans graduation
ax.arrow(min(x), 0, max(x)-min(x), 0.,
         fc='k', ec='k', 
         head_width=.1, head_length=.1,
         length_includes_head= True, clip_on = False) 
ax.arrow(0, min(sinus), 0, max(sinus)-min(sinus),
         fc='k', ec='k', 
         head_width=.1, head_length=.1,
         length_includes_head= True, clip_on = False) 

# Affichage du graphique
plt.axis('off')
plt.plot(x, sinus, label="$f:\mathbb{R} \longrightarrow \mathbb{R}$\n $\ \ x \longmapsto \sin(x)$")
plt.legend()
plt.show()
         #

Ajouter un curseur

In [11]:
from matplotlib.widgets import Cursor
# une figure interactive
%matplotlib notebook           

# la fonction subplots renvoie la 
fig, ax = plt.subplots()
cursor  = Cursor(ax, color='red', linewidth=1)

x       = np.linspace(-10, 10, 100)
y       = np.sin(x)
plt.grid()
plt.plot(x, y)

plt.show()