Introduction à la visualisation de données avec python et matplotlib

Pour suivre nos dernières actualités n'oubliez pas de vous abonner :


Une image vaut mille mots, et avec la bibliothèque matplotlib de Python, il faut heureusement beaucoup moins que mille lignes de code pour créer un graphique de qualité.

Cependant, matplotlib est aussi une bibliothèque massive, et obtenir un bon tracé est souvent obtenu par essais et erreurs.

Utiliser des plots simples pour générer des graphiques de base dans matplotlib est assez facile, mais utiliser habilement les 98% des fonctionnalités restantes de la bibliothèque peut être intimidant.

Cet article est une revue de matplotlib du niveau débutant à intermédiaire

Vous trouverez ici un qui mélange de théorie et des exemples.

Bien que l'apprentissage par l'exemple puisse être extrêmement instructif, il est également utile d'avoir une compréhension théorique. Sur le fonctionnement interne de la de la bibliothèque et sur ces spécificités.


Voilà ce qu'on va couvrir :

  • Les concepts clés du design de matplotlib
  • Comprendre les subplots (layers/ calques) plt.subplots()
  • Visualisation de tableaux avec matplotlib
  • Traçage avec la combinaison pandas + matplotlib


Cet article suppose que l'utilisateur connaît NumPy. 

Nous utiliserons principalement la méthode du module numpy.random pour générer des données, à partir d'échantillons provenant de différentes distributions statistiques.

Si vous n'avez pas déjà installé matplotlib, je vous invite à aller ici pour une visite guidée avant de commencer.

Pourquoi Matplotlib peut-il être déroutant ?

Apprendre matplotlib peut parfois être un processus frustrant. 

Le problème n'est pas que la documentation de matplotlib fait défaut ...la documentation est en fait étendue. 

Mais les problèmes suivants peuvent poser certains défis :

  • La bibliothèque elle-même est énorme, avec environ 70 000 lignes de code au total.
  • Matplotlib héberge plusieurs interfaces différentes (façons de construire une figure) et est capable d'interagir avec une palette d'interfaces qui ne se ressemblent pas. 
  • Matplotlib gère à la fois le traitement du processus de rendu, il gère la mise en forme des graphiques, et aussi la structure interne au code.
  • Comme la librairie est très volumineuse et contient de nombreux exemples, il n’est pas rare d’avoir une documentation qui n’est pas à jour … voir obsolète. Certains exemples peuvent être réduits à hauteur de 70% de code en moins.


Hiérarchie d'objets Matplotlib

La hiérarchie d'objets est un concept important de matplotlib

Si vous avez travaillé sur un tutoriel d'introduction à matplotlib, vous avez probablement utilisé la méthode plt.plot([1, 2, 3])

Cette méthode cache le fait qu'un tracé est en réalité une hiérarchie d'objets Python imbriqués.

Une "hiérarchie" signifie ici qu'il existe une structure arborescente d'objets matplotlib sous chaque parcelle de code.

Ce qui veut dire un peu à la manière de photoshop et des autres outils de design, que matplotlib possède lui aussi son système de calques

Que chacun de ces calques on un positionnement par couches, qui nous permet de savoir quelle image ou graphique est située  au premier ou au dernier plan.

L’objet figure est le conteneur (ndlr : conteneur de calques) le plus reculé d'un graphique matplotlib.


Cet objet  figure peut contenir des sous objets Axes (niveau de calques).


Attention !!!!

Le terme Axes au pluriel porte à confusion.

Car un axe (axis) au singulier se traduit comme un tracé ou un graphique individuel

Alors que le pluriel Axes , est l’objet sur lequel va être dessiné le graphique. 

Axes est le calque (la feuille) alors que l'axe est le dessein qui se trouve dessus.

Voici une représentation schématique d’une figure matplotlib.


Chart


6 - Au dernier niveau de profondeur on retrouve l’objet figure de matplotlib, qui est si l’on puit dire le patron de l’objet final.


5 - Ensuite juste au niveau supérieur on y place les objets Axes qui sont les calques qui vont recevoir les desseins.


4 - Sur les Axes  on y trace un schéma orthonormé pour recevoir les abscisses et ordonnées. (axis dans le langage matplotlib)


3 - Afin de bien reconnaître les données poussées dans un graphique on aura tendance à utiliser les labels (xlabel et ylabel).


2 - Le terme title apposé au dessus du graphique tracé correspond à la méthode matplotlib.pyplot.title() ou si alias a plt.title()


1 - Quand tout est prêt et que l’on a bien renseigné les informations … matplotlib, va se mettre à tracer la courbe (ou autre design de choix)


Voici une illustration de cette hiérarchie en action. 

Ne vous inquiétez pas si vous n'êtes pas tout à fait familier avec cette notation, que nous aborderons plus loin :


REPL

-------------------------------------------------------------

>>> fig, _ = plt.subplots()

>>> type(fig)

[RESULT] <classe'matplotlib.figure.figure.> Figure'>

--------------------------------------------------------------


Ci-dessus, nous avons créé deux variables avec plt.subplots(). 

Au travers un tuple.

Dans la variable figure on stocke un objet spécifique à matplotlib. 

La seconde est une variable "jetable" dont nous n'avons pas encore besoin, notée d'un underscore. 

En utilisant cette syntaxe, il est maintenant plus facile de parcourir la hiérarchie figure, axes, axe (axis), plot  

Si on comprend la structure d’un objet on peut en savoir plus sur la première couche de l'axe des y du premier objet Axes :


REPL

-------------------------------------------------------------------

>>> one_tick = fig.axes[0].yaxis.get_major_ticks()[0].

>>> type(one_tick)

[RESULT] <classe'matplotlib.axis.YTick'>

-----------------------------------------------------------------------


Ci-dessus, fig (une instance de classe Figure) a plusieurs Axes (une liste, pour laquelle nous prenons le premier élément). 

Chaque axe a un yaxis et un xaxis, chacun d'eux ayant une collection de "ticks" (supérieurs ou inférieurs). Ici on affiche l’objet correspondant au ticks supérieur des ordonnées (Y).

Anatomie plus précise d’une figure matplotlib:

Chart: anatomy of a figure

(Dans le vrai style matplotlib, la figure ci-dessus est créée dans les docs matplotlib. ici.)


Stateful Versus Stateless Approaches ?

Très bien, nous avons besoin d'un autre élément de théorie avant de pouvoir nous concentrer sur les visualisations : la différence entre les interfaces stateful (state-based, state-machine) et stateless (object-oriented, POO).

Maintenant nous importons le module pyplot de matplotlib

et nous créons l’alias plt (convention)


REPL

---------

import numpy as np

import matplotlib.pyplot as plt

----------


Presque toutes les fonctions de pyplot, telles que plt.plot(), se réfèrent implicitement soit à une figure et à des axes courants existants, soit à leur création si aucune n'existe. 

Caché dans les docs de matplotlib se trouve cet extrait utile :

Avec pyplot, des fonctions simples permettent d'ajouter des éléments de tracé (lignes, images, texte, etc.) aux axes courants de la figure courante.


Les utilisateurs hardcore ex-MATLAB peuvent choisir de formuler ceci en disant quelque chose comme, "plt.plot() est une interface state-machine qui suit implicitement le chiffre actuel !" En anglais, cela signifie que :

  • L'interface fait ses appels avec plt.plot() et d'autres fonctions de pyplot de niveau supérieur. 
  • Il n'y a qu'une seule figure ou un seul axe que vous manipulez à un moment donné, et vous n'avez pas besoin de vous y référer explicitement.
  • Modifier directement les objets sous-jacents est l'approche orientée objet. Nous le faisons généralement en appelant les méthodes d'un objet Axes, qui est l'objet qui représente un tracé (ou courbe) lui-même.

Le déroulement de ce processus, à un niveau élevé, ressemble à ceci :

Flow

La plupart des fonctions de pyplot existent aussi en tant que méthodes de la classe matplotlib.axes.axes.

C'est plus facile à comprendre en regardant sous le capot.


Plt.plot() peut être réduit à environ cinq lignes de code :

SCRIPT # matplotlib/pyplot.py (dans matplotib directement)

--------------------------


Def plot(*args, **kwargs) :

 " ""Une version abrégée de plt.plot().""""

ax = plt.gca()

return ax.plot(*args, **kwargs)


def gca(**kwargs) :

" """Obtenir les axes actuels de la figure actuelle.""""

etour plt.gcf().gca(**kwargs)

-----------------------------------


Appeler plt.plot() est juste un moyen pratique d'obtenir les Axes courants de la Figure courante et d'appeler sa méthode plot().

C'est ce qu'on entend par l'affirmation que l'interface dynamique "suit toujours implicitement" la courbe qu'elle veut référencer.

Pyplot est le recueil de fonctions qui enveloppent l'interface orientée objet de matplotlib. 

Par exemple, avec plt.title(), il existe des méthodes setter et getter correspondantes dans l'approche POO (programmation orientée objet), ax.set_title() et ax.get_title().


(L'utilisation de getters et setters tend à être plus populaire dans des langages tels que Java mais ça reste est une caractéristique clé de l'approche POO de matplotlib).


plt.title() est traduit dans cette ligne : gca().set_title(s, *args, **kwargs). Voilà ce que ça fait :

  • gca() prend l'axe courant et le renvoie.
  • set_title() est une méthode setter qui définit le titre pour cet objet Axes. La "commodité" ici est que nous n'avions pas besoin de spécifier explicitement un objet Axes avec plt.title().


De même, si vous prenez quelques instants pour regarder la source des fonctions de niveau supérieur comme plt.grid(), plt.legend(), et plt.ylabels(), vous remarquerez qu'ils suivent tous la même structure de délégation aux Axes courants avec gca() et d'appel de certaines méthodes des Axes courants. (C'est l'approche orientée objet sous-jacente !)

Comprendre plt.subplots()

Bon, assez de théorie. Maintenant, nous sommes prêts à tout lier ensemble et à faire un peu dataviz (tracer des beaux graphiques). 

A partir de maintenant, nous nous appuierons principalement sur l'approche sans état (orientée objet), qui est plus personnalisable et qui s'avère utile lorsque les graphiques deviennent plus complexes.

La façon prescrite pour créer une figure avec un seul axe sous l'approche POO se fait intuitivement avec plt.subplots(). 

C'est vraiment la seule fois que l'approche POO utilise pyplot, pour créer une figure et des axes :


>>> fig, ax = plt.subplots()


Ci-dessus, nous avons profité d’un itérateur pour assigner une variable séparée à chacun des deux résultats de plt.subplots(). 

Notez que nous n'avons pas passé d'arguments à subplots() ici. 

L'appel par défaut est subplots(nrows=1, ncols=1). 

Par conséquent, ax est un objet AxesSubplot unique :


REPL

-----------------------

>>> type(ax)

[RESULT] <classe'matplotlib.axes._subplots.AxesSubplot'>.

--------------------------


Nous pouvons appeler ses méthodes d'instance pour manipuler le tracé de la même manière que nous appelons les fonctions des pyplots. 

Illustrons à l'aide d'un graphique à aires empilées de trois séries chronologiques :


----------------------------------------

>>> rng = np.arange(50)

>>> rnd = np.random.randint(0, 10, size=(3, rng.size))

>>> années = 1950 + rng


>>> fig, ax = plt.subplots(figsize=(5, 3))

>>> ax.stackplot(years, rng + rnd, labels=['Eastasia','Eurasia','Oceania']))

>>> ax.set_title('Croissance de la dette combinée dans le temps')

>>> ax.legend(loc='upper left')

>>> ax.set_ylabel('Dette totale')

>>> ax.set_xlim(xmin=yrs[0], xmax=yrs[-1])

>>> fig.tight_layout()


-------------------------------------------


Voici ce qui se passe en haut :

  • Après avoir créé trois séries temporelles aléatoires, nous avons défini une figure (fig) contenant un axes (un graphique, un axe).
  • Nous appelons les méthodes d'ax directement pour créer un diagramme de zone empilée et pour ajouter une légende, un titre et une étiquette sur l'axe des y. Sous l'approche orientée objet, il est clair que tous ces attributs sont des attributs de ax.
  • tight_layout() s'applique à l'objet figure dans son ensemble pour nettoyer le remplissage des espaces blancs ou mal gérés.
Chart: debt growth over time

Examinons un exemple avec plusieurs subplots (Axes) dans une figure, en traçant deux tableaux corrélés qui sont dessinés à partir de l'élément distribution discrète et uniforme :



-------------------------------------------------------------------

>>> x = np.random.randint(low=1, high=11, size=50)

>>> y = x + np.random.randint(1, 5, size=x.size)

>>> data = np.column_stack((x, y)))


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

...                                figsize=(8, 4))


>>> ax1.scatter(x=x, y=y, marker='o', c='r', edgecolor='b')

>>> ax1.set_title('Scatter : $x$ versus $y$')

>>> ax1.set_xlabel('$x$')

>>> ax1.set_ylabel('$y$')


>>> ax2.hist(data, bins=np.arange(data.min(), data.max()),

...          label=('x','y'))

>>> ax2.legend(loc=(0.65, 0.8))

>>> ax2.set_title('Fréquences de $x$ et $y$')

>>> ax2.yaxis.tick_right()


--------------------------------------------------------------------------


Charts

Il y a un peu plus de choses qui se passent dans cet exemple :

  • Parce que nous créons une figure "1x2", le résultat retourné par plt.subplots(1, 2) est maintenant un objet Figure et un tableau NumPy d'objets Axes.

 (Vous pouvez l'inspecter avec fig, axs = plt.subplots(1, 2) et jeter un coup d'oeil à axs).

  • Nous traitons ax1 et ax2 individuellement, ce qui serait difficile à faire avec l'approche stateful. La dernière ligne est une bonne illustration de la hiérarchie des objets, où l'on modifie l'axe des yaxis appartenant au deuxième axe, en plaçant ses ticks et ticklabels vers la droite.
  • Le texte à l'intérieur des signes dollar utilise TeX pour mettre les variables en italique.

Rappelez-vous que plusieurs Axes peuvent être enfermés dans ou "appartiennent" à une figure donnée. Dans le cas ci-dessus, fig.axes nous donne une liste de tous les objets Axes :


REPL

-----------------------------

>>> (fig.axes[0] and ax1, fig.axes[1] and ax2)

[RESULT] (True, True)

-----------------------------


(fig.axes est en minuscules, pas en majuscules. Il est indéniable que la terminologie est un peu confuse.)

Pour aller plus loin, nous pourrions également créer une figure contenant une grille 2x2 d'objets Axes :

REPL

-----------------------------

>>> fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(7, 7))

-----------------------------


C’est quoi un axe (axis)?

Il ne s'agit plus d'un Axes unique, mais d'un tableau numérique bidimensionnel :


REPL

------------------

>>> type(ax)

[RESULT] numpy.ndarray.


>>> ax

[RESULT] array(

[

[<matplotlib.axes._subplots.AxesSubplot objet at 0x1106daf98>,         <matplotlib.axes._subplots.AxesSubplot objet at 0x113045c88>],


[<matplotlib.axes._subplots. AxesSubplot objet à 0x11d573cf8>,         <matplotlib.axes._subplots.AxesSubplot objet at 0x1130117f0>]

], dtype=objet)


>>> ax.shape

[RESULT]  (2, 2)


--------------------------


Ceci est réaffirmé par le docstring :


"ax peut être soit un seul objet matplotlib.axes.axes, soit un tableau d'objets Axes si plusieurs subplots ont été créées."

Nous devons maintenant appeler des méthodes de traçage sur chacun de ces Axes (mais pas le tableau NumPy, qui est juste un conteneur dans ce cas). 

Une façon courante d'y remédier est d'utiliser le déballage itérable après avoir aplati le tableau pour qu'il soit unidimensionnel (1D array) :



Nous aurions également pu le faire avec ((ax1, ax2), (ax3, ax4)) = ax, mais la première approche tend à être plus flexible.

Pour illustrer quelques fonctionnalités plus avancées des subplots, extrayons quelques données macroéconomiques californiennes sur le logement extraites d'une archive tar compressée, en utilisant io, tarfile, et urllib de la bibliothèque standard de Python.



La variable "response" y ci-dessous, pour utiliser le terme statistique, est la valeur moyenne des habitations d'une région. 

pop et age sont respectivement la population et l'âge moyen des habitations de la région :



Définissons ensuite une "add_titlebox" qui place une zone de texte à l'intérieur d'un tracé et agit comme un "titre dans le tracé" :



Nous sommes prêts à tracer une courbe. 

Le module grdspec  de Matplotlib permet de personnaliser davantage les subplots. 

Le grid subplot2grid() de pyplot interagit parfaitement avec ce module. 


Disons que nous voulons créer une mise en page comme celle-ci :

Empty gridspec

En haut, nous avons une grille de 3x2. ax1 est deux fois plus haut et plus large que ax2/ax3, ce qui signifie qu'il prend deux colonnes et deux lignes.

Empty gridspec

Le deuxième argument passé à subplot2grid() est l'emplacement (ligne, colonne) des Axes dans la grille :


---------------------------------

>>> gridsize = (3, 2)

>>> fig = plt.figure(figsize=(12, 8))

>>> ax1 = plt.subplot2grid(gridsize, (0, 0), colspan=2, rowspan=2)

>>> ax2 = plt.subplot2grid(gridsize, (2, 0))

>>> ax3 = plt.subplot2grid(gridsize, (2, 1))

----------------------------------------------


Maintenant, nous pouvons procéder comme d'habitude, en modifiant chaque Axes individuellement :



Charts

Ci-dessus,  la méthode colorbar() (différente de ColorMap précédemment) est appelée directement sur la Figure, plutôt que sur les Axes. 

Son premier argument est le résultat de ax1.scatter(), qui fonctionne comme un mappage des valeurs y un peu du même style que le paramètre ColorMap.

Visuellement, il n'y a pas beaucoup de différenciation dans la couleur (la variable y).

Par contre à mesure que l'on monte et descend sur l’axe des ordonnées, on comprend que plus l’âge de la maison vieillit plus la valeur patrimoniale de la maison augmente.

 Plus la maison est a âgée plus elle coûte chère 


Les "figures" dans les coulisses


Chaque fois que vous appelez plt.subplots() ou plt.figure() qui moins fréquemment utilisé (qui crée une figure, sans Axes), vous créez un nouvel objet figure que matplotlib garde en mémoire.

Plus tôt, nous avons fait allusion au concept d'une figure actuelle et d'axes actuels. 

Par défaut, il s'agit des figures et des axes les plus récemment créés, que nous pouvons afficher avec la fonction intégrée id() pour afficher l'adresse de l'objet en mémoire :


REPL

----------------------------

>>> fig1, ax1 = plt.subplots()


id(fig1) >>> id(fig1)

[RESULT] 4525567840


>>> id(plt.gcf())) # `fig1` est le chiffre actuel.

[RESULT] 4525567840


>>> fig2, ax2 = plt.subplots()

>>> id(fig2) == id(plt.gcf()) # Le chiffre actuel a changé en `fig2`.

[RESULT] True


--------------------------------------------------


Après la routine ci-dessus, le chiffre actuel est fig2, le dernier chiffre créé. 


Cependant, les deux figures traînent toujours en mémoire, chacune avec un numéro d'identification correspondant (1-indexed, dans le style MATLAB) :

REPL

----------------------------

>>> plt.get_fignums()

[RESULT] [1, 2]

-----------------------------


Un moyen utile d'obtenir toutes les figures elles-mêmes est de mapper plt.figure() à chacun de ces nombres entiers :


REPL

----------------------------

>>> def get_all_figures() :

....    return[plt.figure(i) for i in plt.get_fignums()]]


>>> get_all_figures()

Figure à 0x10dbeaf60>,

[RESULT] <Figure à 0x1234cb6d8d8>])

-----------------------------


Soyez conscient de cela si vous exécutez un script dans lequel vous créez un groupe de figures.

 Vous voudrez fermer explicitement chacun d'entre eux après utilisation pour éviter une erreur de mémoire.

 Par lui-même, plt.close() ferme la figure courante, plt.close(num) ferme le numéro de figure num, et plt.close('all') ferme toutes les fenêtres de figure :


REPL

----------------------------

>>> plt.close('all')

>>> get_all_figures()

[RESULT] []

----------------------------


Une explosion de couleurs : imshow() et matshow()

Bien que ax.plot() soit l'une des méthodes de traçage les plus courantes sur un Axes, il en existe une foule d'autres. (Nous avons utilisé ax.stackplot() ci-dessus. Vous pouvez trouver la liste complète ici.)

Les méthodes les plus utilisées sont imshow() et matshow(), cette dernière étant une enveloppe autour de la première. 

Ceux-ci sont utiles chaque fois qu'un tableau numérique brut peut être visualisé sous la forme d'une grille colorée.

Tout d'abord, créons deux grilles distinctes avec une indexation numérique fantaisiste :



Ensuite, nous pouvons les mettre en correspondance avec leurs représentations d'images. 

Dans ce cas spécifique, nous basculons "off" toutes les étiquettes d'axes et les coches en utilisant une compréhension dictionnaire et en passant le résultat à ax.tick_params() :



Ensuite, nous pouvons utiliser un pour désactiver la grille, et appeler matshow() sur chaque Axes.

Enfin, nous devons mettre la barre de couleurs dans ce qui est techniquement un nouvel axe dans la figure.

 Pour cela, nous pouvons utiliser un peu une fonction ésotérique du plus profond de matplotlib :


Heat maps

Savoir dessiner des courbes avec pandas

La bibliothèque pandas est devenue populaire non seulement parce qu'elle est puissante mais aussi pour ses méthodes pratiques de traçage prédéfinies.

Il est intéressant de noter que les méthodes de traçage de courbes via pandas ne sont en réalité que des wrappers pratiques autour d’ appels matplotlib existants.

C'est-à-dire que la méthode plot() sur les séries et DataFrame de pandas est un wrapper autour de plt.plot(). 

Exemple : si l'index du DataFrame est constitué de dates, gcf().autofmt_xdate() est appelé en interne par pandas pour obtenir la figure courante et pour bien auto formater dans l'axe x.

En retour, rappelez-vous que plt.plot() (l'approche stateful) est implicitement consciente de la figure actuelle et des axes actuels, donc pandas suit l'approche basée sur l'état (stateful) par extension.

Nous pouvons expliquer cette "chaîne" d'appels de fonctions avec un peu d'introspection. 

Tout d'abord, construisons une série pandas simple, en supposant que nous commencions par une nouvelle session d'interprétation :


Cette architecture interne est utile pour savoir quand vous mélangez des méthodes pour tracer des courbes via pandas avec des appels matplotlib traditionnels

Exemple ci-dessous en traçant la moyenne mobile d'une série temporelle financière largement surveillée.

ma est une série pandas pour laquelle nous pouvons appeler ma.plot() (la méthode pandas), et ensuite personnaliser en récupérant les axes qui ont été créé par cet appel (plt.gca()), pour matplotlib référence :


Volatility Regime State diagram

Il se passe beaucoup de choses en haut :

  • ma est une moyenne mobile sur 90 jours de l'indice VIX, une mesure des attentes du marché quant à la volatilité à court terme des actions. state est un regroupement de la moyenne mobile dans différents états de régime. Un VIX élevé est perçu comme le signe d'un niveau de peur accru sur le marché.
  • cmap est un ColorMap - un objet matplotlib qui est essentiellement un mappage des setters aux couleurs RGBA. 


Toute carte de couleurs peut être inversée en ajoutant '_r', donc 'RdYlGn_r' est la carte de couleurs inversée Rouge-Jaune-Vert. Matplotlib dispose d'un outil pratique pour guide de référence visuel de ColorMaps dans sa documentation.

  • Le seul vrai appel de pandas que nous faisons ici est ma.plot(). Ceci appelle plt.plot() en interne, donc pour intégrer l'approche orientée objet, nous devons obtenir une référence explicite aux Axes courants avec ax = plt.gca().


  • Le deuxième morceau de code crée des blocs remplis de couleurs qui correspondent à chaque bin d'état. cmap([0.2, 0.4, 0.6, 0.8]) dit, "Obtenez-nous une séquence RGBA pour les couleurs aux 20ème, 40ème, 60ème et 80ème percentiles du spectre ColorMaps'". enumerate() est utilisé parce que nous voulons faire correspondre chaque couleur RGBA à un état.

Pandas est également livrés avec une petite quantité de de méthodes plus avancées .


Récapitulation

Comme le montrent certains des exemples ci-dessus, il est évident que matplotlib peut être une bibliothèque technique à syntaxe lourde. 

La création d'un graphique prêt pour la production nécessite parfois une demi-heure de recherche sur Google et la combinaison d'un méli-mélo de lignes afin d'affiner un tracé.

Cependant, comprendre comment les interfaces de matplotlib interagissent est un investissement qui peut s'avérer payant.

Comme l'a conseillé Dan Bader de Real Python, prendre le temps de disséquer le code plutôt que de recourir à la solution de "copier coller" de Stack Overflow tend à être une solution plus intelligente à long terme.

S'en tenir à l'approche orientée objet peut vous épargner des heures de frustration lorsque vous voulez passer à la création d’oeuvre d’arts

Plus de ressources

D'après la documentation matplotlib :

Annexe A : Configuration et style

Si vous avez suivi ce tutoriel, il est probable que les courbes qui apparaissent à l'écran n'ont pas le même style que ceux présentés ici.

Matplotlib offre deux façons de configurer le style d'une manière uniforme sur différentes courbes:

  1. En personnalisant un Fichier matplotlibrc
  2. En modifiant vos paramètres de configuration de manière interactive, ou à partir d'un script.py.

Un fichier matplotlibrc (Option #1 ci-dessus) est essentiellement un fichier texte spécifiant les paramètres personnalisés par l'utilisateur qui sont mémorisés entre les sessions Python. 


Sous Mac OS X, cela réside normalement dans ~/.matplotlib/matplotlibrc.

Conseil rapide : GitHub est un endroit idéal pour conserver les fichiers de configuration. Je garde le mien ici. Assurez-vous simplement qu'ils ne contiennent pas d'informations personnelles identifiables ou privées, comme des mots de passe ou des clés privées SSH !

Vous pouvez également modifier vos paramètres de configuration de manière interactive (option 2 ci-dessus).

Lorsque vous importez matplotlib.pyplot comme plt, vous avez accès à un objet rcParams qui ressemble à un dictionnaire Python de paramètres. 

Tous les objets du module commençant par "rc" sont un moyen d'interagir avec vos styles et paramètres de courbes (tracé) :


De ceux-là :

  • plt.rcdefaults() restaure les paramètres rc à partir des valeurs par défaut internes de matplotlib, qui sont listées dans plt.rcParamsDefault


Ceci annulera (écrasera) tout ce que vous avez déjà personnalisé dans un fichier matplotlibrc.


  • plt.rc() est utilisé pour régler les paramètres de manière interactive.


  • plt.rcParams est un objet de type dictionnaire (mutable) qui vous permet de manipuler les paramètres directement. Si vous avez des paramètres personnalisés dans un fichier matplotlibrc, ceux-ci seront reflétés dans ce dictionnaire.

Avec plt.rc() et plt.rcParams, ces deux syntaxes sont équivalentes pour ajuster les paramètres :

Notamment, la classe Figure alors utilise certains de ces arguments comme arguments par défaut.

De même, un style n'est qu'un ensemble prédéfini de paramètres personnalisés. Pour afficher les styles disponibles, utilisez :


Pour définir un style, faites cet appel :

Vos intrigues vont maintenant prendre un nouveau look :

Chart

Cet exemple complet est disponible ici.

Pour s'inspirer, matplotlib en garde quelques unes à titre de référence également.

Cet article est une traduction (à partir de l'anglais), modifiée et améliorée

Tu as bien aimé l'article ou tu as mal aux yeux :

Le lien du PDF

Article écrit par :
Mikael Monjour
Data et Automatisation