7. Les graphiques

Matplotlib est une bibliothèque complète capable de générer des graphiques de haute qualité. Matplotlib contient à la fois des fonctions de haut niveau produisant des types de figures spécifiques, par exemple un simple tracé linéaire ou un graphique à barres, ainsi qu'une API de bas niveau permettant de créer des graphiques hautement personnalisés. Ce chapitre couvre les bases de la création de figures et ne fait qu'effleurer le champs des applications de matplotlib. Des informations complémentaires sont disponibles sur le site Web de matplotlib ou dans des livres consacrés à la production de graphiques de qualité d'impression à l'aide de matplotlib. Tout au long de cette partie, les modules suivants seront importés.

In [ ]:
import matplotlib.pyplot as plt
import scipy.stats as stats
import numpy as np 

7.1 seaborn

seaborn est un paquet Python qui fournit un certain nombre de figures avancées de visualisation de données. Il fournit également une amélioration générale de l'apparence par défaut des figures produites par matplotlib, et je recommande donc de l'utiliser c'est par défaut.

In [ ]:
import seaborn as sns

Toutes les figures de cette parties seront produites avec seaborn chargé, en utilisant les options par défaut. L'arrière-plan de la grille sombre peut être échangé contre une grille claire ou aucune grille à l'aide de sns.set(style = 'whitegrid') (grille légère) ou de sns.set(style = 'blanc') (pas de grille, très similaire à matplotlib).

7.2 Figures en 2D

7.2.1 autoscale et tight_layout

Deux fonctions, plt.autoscale et plt.tight_layout, amélioreront généralement l'apparence des figures. autoscale peut être utilisée pour définir des limites serrées dans les axes d’une figure et tight_layout supprime l’espace perdu autour d’une figure. Celles-ci ont été utilisées dans les figures de cette partie. Elles seront utilisées par défaut et rarement mentionnées.

7.2.2 Tracés linéaires

In [ ]:
y = np.random.randn(100)
plt.plot(y)
plt.autoscale(tight='x')
plt.tight_layout()

Une forme plus flexible ajoute une chaîne de format qui comporte 1 à 3 éléments: une couleur, représentée par une lettre (par exemple, g pour le vert), un symbole de marqueur qui est soit une lettre d'un symbole (par exemple, s pour carré, ^ pour triangle en haut ) et un style de ligne, qui est toujours un symbole ou une série de symboles. Dans l'exemple suivant, 'g--' indique le vert (g) et la ligne pointillée (-).

In [ ]:
plt.plot(y,'g--')

Les couleurs :

  • b : blue
  • g : green
  • r : red
  • c : cyan
  • m : magenta
  • y : yellow
  • k : black
  • w : white

Consulter l'aide la fonction plt.plot pour plus de détail.

Le comportement par défaut consiste à utiliser une ligne bleue continue sans marqueur (sauf s’il y a plus d’une ligne, auquel cas les couleurs modifieront, dans l’ordre, celles de la colonne Couleurs, en ignorant le blanc). La chaîne de formatage contient 1 ou plus ou les trois catégories d’informations de formatage. Par exemple, kx-- produirait une ligne pointillée noire avec des croix marquant les points, *: produirait une ligne pointillée avec la couleur par défaut en utilisant des étoiles pour marquer des points et yH produirait une ligne jaune continue avec un marqueur hexagonal. Lorsque plot est appelé avec un tableau, les valeurs par défaut de l'axe des abscisses 1,2,... sont utilisés. plot(x, y) peut être utilisé pour tracer des valeurs x spécifiques versus des valeurs y.

In [ ]:
x = np.cumsum(np.random.rand(100))
plt.plot(x,y,'r-')

Bien que les chaînes de format soient utiles pour ajouter rapidement des couleurs ou des styles de ligne significatifs à un tracé, elles n'exposent qu'une gamme limitée de personnalisations disponibles. L'exemple suivant montre comment les arguments sont utilisés pour ajouter des personnalisations à un tracé.

In [ ]:
plt.plot(x,y,alpha = 0.5, color = '#FF7F00', \
... label = 'Line Label', linestyle = '-.', \
... linewidth = 3, marker = 'o', markeredgecolor = '#000000', \
... markeredgewidth = 2, markerfacecolor = '#FF7F00', \
... markersize=30)

7.2.3 Diagramme en baton

bar produit des graphiques à barres utilisant deux tableaux à une dimension. Le premier spécifie le rebord gauche des barres et le second les hauteurs de barre.

In [ ]:
y = np.random.rand(5)
x = np.arange(5)
plt.bar(x,y)

Les graphiques à barres prennent des arguments de mots clés pour modifier les couleurs et la largeur des barres.

In [ ]:
plt.bar(x,y, width = 0.5, color = '#FF7F00', edgecolor = '#000000', linewidth = 5)

Enfin, barh peut être utilisé à la place de la barre pour produire un graphique à barres horizontales.

In [ ]:
colors = sns.color_palette('colorblind')
plt.barh(x, y, height = 0.5, color = colors, edgecolor = '#000000', linewidth = 5)

7.2.4 Pie Charts (c'est mieux en anglais)

pie réduit les diagrammes à secteurs à l'aide d'un tableau de données à 1 dimension (les données peuvent avoir n'importe quelle valeur et il n'est pas nécessaire que leur somme soit égale à 1).

In [ ]:
y = np.random.rand(5)
y = y/sum(y)
y[y<.05] = .05
plt.pie(y)

Les pie charts peuvent être modifiés à l'aide d'un grand nombre d'arguments, notamment des étiquettes et des couleurs personnalisées. Dans cet exemple, les couleurs sont générées à l’aide du générateur de palette de seaborn avec 8 couleurs, bien que seules les 5 premières soient utilisées, de sorte que la couleur la plus sombre ne soit pas trop sombre pour que le texte puisse être lu. Des vues éclatées d'un pie chart peuvent être produites en fournissant un vecteur de distances à l'argument. Notez que autopct = '% 2.0f' utilise une ancienne chaîne de formatage pour formater les étiquettes numériques.

In [ ]:
explode = np.array([.2,0,0,0,0])
colors = sns.dark_palette("skyblue", 8, reverse=True)
labels = ['One', 'Two', 'Three', 'Four', 'Five']
plt.pie(y, explode = explode, colors = colors, labels = labels, autopct = '%2.0f', shadow = True)

7.2.5 Les histogrammes

Les histogrammes peuvent être produits en utilisant la fonction hist. Cet exemple définit le nombre de classes à utiliser à l'aide du mot clé bins.

In [ ]:
x = np.random.randn(1000)
plt.hist(x, bins = 30)

Les histogrammes peuvent être encore modifiés en utilisant des arguments de mots clés. Dans l'exemple suivant, cumulative=True génère l'histogramme cumulatif.

In [ ]:
plt.hist(x, bins = 30, cumulative=True, color='#FF7F00')

7.3 Figures 2D avancées

7.3.1 Plusieurs figures

Dans certains cas, il est avantageux d’avoir plusieurs graphiques ou courbes sur la même figure. La mise en œuvre est simple: utiliser figure pour initialiser la fenêtre de la figure, puis utiliser add_subplot. Des sous-graphes sont ajoutés à la figure en utilisant une grille avec $m$ lignes et $n$ colonnes où $1$ est le coin supérieur gauche, $2$ le droit de $1$ et ainsi de suite jusqu'à la fin d'une ligne, où l'élément suivant est en dessous de $1$. Par exemple , les figures d'un subplot $3 \times 2$ ont des indices $$ \begin{align*} \begin{pmatrix} 1 & 2\\ 3 & 4\\ 5 & 6\\ \end{pmatrix} \end{align*} $$ add_subplot est appelé en utilisant la notation add_subplot(mni) ou add_subplot(m,n,i) où $m$ est le nombre de lignes, $n$ le nombre de colonnes et $i$ l’indice de la sous-parcelle.

Noter que add_subplot doit être appelé comme une méthode de la figure. Noter que le bloc de code suivant est suffisamment long pour qu’il ne soit pas pratique pour l’exécuter de manière interactive. draw() est donc utilisé pour forcer la mise à jour de la fenêtre afin de garantir la visibilité de tous les tracés et graphiques.

In [ ]:
from matplotlib.pyplot import figure, plot, bar, pie, draw, scatter
from numpy.random import randn, rand
from numpy import sqrt, arange
fig = figure()
# Add the subplot to the figure
# Panel 1
ax = fig.add_subplot(2, 2, 1)
y = randn(100)
plot(y)
ax.set_title('1')
# Panel
2
y = rand(5)
x = arange(5)
ax = fig.add_subplot(2, 2, 2)
bar(x, y)
ax.set_title('2')
# Panel 3
y = rand(5)
y = y / sum(y)
y[y < .05] = .05
ax = fig.add_subplot(2, 2, 3)
pie(y, colors=colors)
ax.set_title('3')
# Panel 4
z = randn(100, 2)
z[:, 1] = 0.5 * z[:, 0] + sqrt(0.5) * z[:, 1]
x = z[:, 0]
y = z[:, 1]
ax = fig.add_subplot(2, 2, 4)
scatter(x, y)
ax.set_title('4')
draw()

7.3.2 ajout d'un titre et d'une légende

Les titres sont ajoutés avec title et les légendes sont ajoutés avec legend. La légende nécessite que les lignes aient des étiquettes. C'est pourquoi 3 appels pour plot - chaque série a sa propre étiquette.

In [ ]:
x = np.cumsum(randn(100,3), axis = 0)
plot(x[:,0],'b-',label = 'Series 1')
plot(x[:,1],'g-.',label = 'Series 2')
plot(x[:,2],'r:',label = 'Series 3')
plt.legend()
plt.title('Basic Legend')

legend prend des arguments mots-clés qui peuvent être utilisés pour changer d’emplacement (loc et un entier, voir la doc), supprimer le cadre (frameon) et ajouter un titre à la zone de légende(title).

In [ ]:
plot(x[:,0],'b-',label = 'Series 1')
plot(x[:,1],'g-.',label = 'Series 2')
plot(x[:,2],'r:',label = 'Series 3')
plt.legend(loc = 0, frameon = False, title = 'The Legend')
plt.title('Improved Legend')

7.4 Figures 3D

La qualité des figures en 3D de matplotlib est nettement plus faible que celle des figures en 2D, mais elle est généralement suffisante pour la plupart des applications (d'autant plus que les graphiques 3D sont rarement nécessaires).

7.4.1 traçés linéaires

Le tracé en 3D est pratiquement identique au tracé en 2D, sauf que 3 vecteurs à une dimension sont nécessaires: $x$, $y$ et $z$ (hauteur). Cet exemple simple montre comment plot peut être utilisé avec l'argument mot-clé $zs$ pour construire un tracé d'une ligne en 3D. La ligne qui définit l’axe à l’aide d’Axed3D (fig.) est essentielle pour la création de graphiques 3D. L'autre nouvelle commande, view_init, est utilisée pour faire pivoter la vue à l'aide de code (la vue peut être pivotée de manière interactive dans la fenêtre de la figure).  

In [ ]:
from math import*
from mpl_toolkits.mplot3d import Axes3D
x = np.linspace(0,6*pi,600)
z = x.copy()
y = np.sin(x)
x = np.cos(x)
fig = plt.figure()
ax = Axes3D(fig) # Different usage
ax.plot(x, y, zs=z, label='Spiral')
ax.view_init(15,45)
plt.draw()

7.4.2 Surface et maillage (filaire)

Les tracés de surfaces et maillage (filaire ou pas) sont parfois utiles pour visualiser les fonctions à 2 entrées (variables), telles que la densité de probabilité bivariée. Cet exemple produit les deux types de tracé pour un la densité d'une gaussienne bivariée avec une moyenne de 0, des variances d'unités et une corrélation de 50%. Le premier bloc de code génère les points à utiliser dans le graphique avec meshgrid et évalue la densité pour toutes les combinaisons de $x$ et $y$.

In [ ]:
from numpy import linspace, meshgrid, mat, zeros, shape, sqrt, matrix
import numpy.linalg as linalg
x = linspace(-3,3,100)
y = linspace(-3,3,100)
x,y = meshgrid(x,y)
z = mat(zeros(2))
p = zeros(shape(x))
R = matrix([[1,.5],[.5,1]])
Rinv = linalg.inv(R)
for i in range(len(x)):
    for j in range(len(y)):
        z[0,0] = x[i,j]
        z[0,1] = y[i,j]
        p[i,j] = 1.0/(2*pi)*sqrt(linalg.det(R))*exp(-(z*Rinv*z.T)/2)

Le bout de code suivant génère un tracé en maillage (filaire) à l'aide de plot_wireframe. La configuration est identique à celle de la ligne 3D et l'appel ax = Axes3D(fig) est à nouveau essentiel. La figure est dessinée à l'aide des tableaux à deux dimensions $x$, $y$ et $p$

In [ ]:
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = Axes3D(fig)
ax.plot_wireframe(x, y, p, rstride=5, cstride=5, color='#AD5300')
ax.view_init(29,80)
plt.draw()

7.4.3 Contours

Les contours ne sont pas techniquement 3D, bien qu'ils soient utilisés comme représentation 2D de données 3D. Comme ils sont finalement en 2D, peu de configuration est nécessaire, mis à part un appel au contour utilisant les mêmes entrées que plot_surface et plot_wireframe.

In [ ]:
fig = plt.figure()
ax = fig.gca()
ax.contour(x,y,p)
plt.draw()

7.5 Fonctions graphiques

figure

figure est utilisé pour ouvrir une fenêtre de figure et peut être utilisé pour générer des axes. fig = figure(n) produit un objet figure avec id $n$ et affecte cet objet à la fig.

add_subplot

add_subplot est utilisé pour ajouter des axes à la figure. ax = fig.add_subplot(111) peut être utilisé pour ajouter des axes basique à une figure. ax = fig.add_subplot(m,n,i) peut être utilisé pour ajouter des axes à une figure avec une grille $m$ par $n$.

close

close sert à fermer une figure. close(n) ferme une figure avec un id $n$, et close('all') ferme toutes les figu#res.

show

show est utilisé pour forcer la mise à jour d'une figure, et suspend l'exécution s'il n'est pas utilisé dans une console interactive (fermer la fenêtre de figure pour reprendre l'exécution). show ne doit pas être utilisé dans des programmes Python autonomes-drawdoit être utilisé.

draw

draw force la mise à jour d'une figure.

7.6 Exporter des figures

L'exportation des figures est simple à l'aide de savefig('filename.ext')ext détermine le type de fichier exporté à produire. ext peut être png, pdf, ps, eps ou svg.

In [ ]:
>>> plot(randn(10,2))
>>> plt.savefig('figure.pdf') # PDF export
>>> plt.savefig('figure.png') # PNG export
>>> plt.savefig('figure.svg') # Scalable Vector Graphics export

savefig a un certain nombre d'arguments mots-clés utiles. En particulier, dpi est utile lors de l'exportation de fichiers png. Le dpi par défaut est $100$.

In [ ]:
>>> plot(randn(10,2))
>>> plt.savefig('figure.png', dpi = 600) # High resolution PNG export