Noter
Cliquez ici pour télécharger l'exemple de code complet
Le cycle de vie d'une parcelle #
Ce didacticiel vise à montrer le début, le milieu et la fin d'une seule visualisation à l'aide de Matplotlib. Nous commencerons par quelques données brutes et terminerons en enregistrant une figure d'une visualisation personnalisée. En cours de route, nous essayons de mettre en évidence certaines fonctionnalités intéressantes et les meilleures pratiques en utilisant Matplotlib.
Noter
Ce tutoriel est basé sur cet excellent article de blog de Chris Moffitt. Il a été transformé en ce tutoriel par Chris Holdgraf.
Une note sur les interfaces explicites et implicites #
Matplotlib a deux interfaces. Pour une explication des compromis entre les interfaces explicites et implicites, voir Matplotlib Application Interfaces (APIs) .
Dans l'interface explicite orientée objet (OO), nous utilisons directement des instances de
axes.Axes
pour créer la visualisation dans une instance de
figure.Figure
. Dans l'interface implicite, inspirée et modélisée par MATLAB, utilise une interface globale basée sur l'état qui est encapsulée dans le
pyplot
module pour tracer les "axes actuels". Voir les tutoriels pyplot pour un aperçu plus approfondi de l'interface pyplot.
La plupart des termes sont simples, mais la principale chose à retenir est que :
La figure est l'image finale qui peut contenir 1 ou plusieurs axes.
Les axes représentent un tracé individuel (ne le confondez pas avec le mot "axe", qui fait référence à l'axe x/y d'un tracé).
Nous appelons des méthodes qui effectuent le traçage directement à partir des Axes, ce qui nous donne beaucoup plus de flexibilité et de puissance pour personnaliser notre tracé.
Noter
En général, préférez l'interface explicite à l'interface pyplot implicite pour le traçage.
Nos données #
Nous utiliserons les données de la publication dont ce didacticiel est dérivé. Il contient des informations sur les ventes d'un certain nombre d'entreprises.
import numpy as np
import matplotlib.pyplot as plt
data = {'Barton LLC': 109438.50,
'Frami, Hills and Schmidt': 103569.59,
'Fritsch, Russel and Anderson': 112214.71,
'Jerde-Hilpert': 112591.43,
'Keeling LLC': 100934.30,
'Koepp Ltd': 103660.54,
'Kulas Inc': 137351.96,
'Trantow-Barrows': 123381.38,
'White-Trantow': 135841.99,
'Will LLC': 104437.60}
group_data = list(data.values())
group_names = list(data.keys())
group_mean = np.mean(group_data)
Mise en route #
Ces données sont naturellement visualisées sous forme de barplot, avec une barre par groupe. Pour ce faire avec l'approche orientée objet, nous générons d'abord une instance de figure.Figure
et
axes.Axes
. La Figure est comme une toile, et les Axes font partie de cette toile sur laquelle nous ferons une visualisation particulière.
Noter
Les figures peuvent avoir plusieurs axes. Pour plus d'informations sur la procédure à suivre, consultez le didacticiel sur la mise en page serrée .
fig, ax = plt.subplots()
Maintenant que nous avons une instance Axes, nous pouvons tracer dessus.
fig, ax = plt.subplots()
ax.barh(group_names, group_data)
<BarContainer object of 10 artists>
Contrôle du style #
Il existe de nombreux styles disponibles dans Matplotlib afin de vous permettre d'adapter votre visualisation à vos besoins. Pour voir une liste de styles, nous pouvons utiliser
style
.
print(plt.style.available)
['Solarize_Light2', '_classic_test_patch', '_mpl-gallery', '_mpl-gallery-nogrid', 'bmh', 'classic', 'dark_background', 'fast', 'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn-v0_8', 'seaborn-v0_8-bright', 'seaborn-v0_8-colorblind', 'seaborn-v0_8-dark', 'seaborn-v0_8-dark-palette', 'seaborn-v0_8-darkgrid', 'seaborn-v0_8-deep', 'seaborn-v0_8-muted', 'seaborn-v0_8-notebook', 'seaborn-v0_8-paper', 'seaborn-v0_8-pastel', 'seaborn-v0_8-poster', 'seaborn-v0_8-talk', 'seaborn-v0_8-ticks', 'seaborn-v0_8-white', 'seaborn-v0_8-whitegrid', 'tableau-colorblind10']
Vous pouvez activer un style avec les éléments suivants :
plt.style.use('fivethirtyeight')
Reprenons maintenant le tracé ci-dessus pour voir à quoi il ressemble :
fig, ax = plt.subplots()
ax.barh(group_names, group_data)
<BarContainer object of 10 artists>
Le style contrôle de nombreux éléments, tels que la couleur, les largeurs de ligne, les arrière-plans, etc.
Personnalisation de l'intrigue #
Maintenant que nous avons un tracé avec l'aspect général que nous voulons, affinons-le pour qu'il soit prêt à être imprimé. Faisons d'abord pivoter les étiquettes sur l'axe des x afin qu'elles apparaissent plus clairement. Nous pouvons accéder à ces étiquettes avec la axes.Axes.get_xticklabels()
méthode :
fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
Si nous souhaitons définir la propriété de plusieurs éléments à la fois, il est utile d'utiliser la pyplot.setp()
fonction. Cela prendra une liste (ou plusieurs listes) d'objets Matplotlib et tentera de définir un élément de style pour chacun.
fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]
On dirait que cela a coupé certaines des étiquettes en bas. Nous pouvons dire à Matplotlib de faire automatiquement de la place aux éléments dans les figures que nous créons. Pour ce faire, nous définissons la autolayout
valeur de nos rcParams. Pour plus d'informations sur le contrôle du style, de la disposition et d'autres fonctionnalités des tracés avec rcParams, consultez
Personnalisation de Matplotlib avec des feuilles de style et rcParams .
plt.rcParams.update({'figure.autolayout': True})
fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]
Ensuite, nous ajoutons des étiquettes au tracé. Pour ce faire avec l'interface OO, nous pouvons utiliser la Artist.set()
méthode pour définir les propriétés de cet objet Axes.
fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
title='Company Revenue')
[(-10000.0, 140000.0), Text(0.5, 87.00000000000003, 'Total Revenue'), Text(86.99999999999997, 0.5, 'Company'), Text(0.5, 1.0, 'Company Revenue')]
Nous pouvons également ajuster la taille de ce tracé à l'aide de la pyplot.subplots()
fonction. Nous pouvons le faire avec l' argument du mot-clé figsize .
Noter
Alors que l'indexation dans NumPy suit la forme (ligne, colonne), l' argument du mot-clé figsize suit la forme (largeur, hauteur). Cela suit les conventions de la visualisation, qui sont malheureusement différentes de celles de l'algèbre linéaire.
fig, ax = plt.subplots(figsize=(8, 4))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
title='Company Revenue')
[(-10000.0, 140000.0), Text(0.5, 86.99999999999997, 'Total Revenue'), Text(86.99999999999997, 0.5, 'Company'), Text(0.5, 1.0, 'Company Revenue')]
Pour les étiquettes, nous pouvons spécifier des directives de formatage personnalisées sous la forme de fonctions. Ci-dessous, nous définissons une fonction qui prend un entier en entrée et renvoie une chaîne en sortie. Lorsqu'ils sont utilisés avec Axis.set_major_formatter
ou
Axis.set_minor_formatter
, ils créeront et utiliseront automatiquement une
ticker.FuncFormatter
classe.
Pour cette fonction, l' x
argument est l'étiquette de graduation d'origine et pos
la position de la graduation. Nous n'en utiliserons x
qu'ici mais les deux arguments sont nécessaires.
def currency(x, pos):
"""The two arguments are the value and tick position"""
if x >= 1e6:
s = '${:1.1f}M'.format(x*1e-6)
else:
s = '${:1.0f}K'.format(x*1e-3)
return s
Nous pouvons ensuite appliquer cette fonction aux étiquettes de notre tracé. Pour ce faire, nous utilisons l' xaxis
attribut de nos axes. Cela vous permet d'effectuer des actions sur un axe précis sur notre tracé.
fig, ax = plt.subplots(figsize=(6, 8))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
title='Company Revenue')
ax.xaxis.set_major_formatter(currency)
Combiner plusieurs visualisations #
Il est possible de dessiner plusieurs éléments de tracé sur la même instance de
axes.Axes
. Pour ce faire, nous devons simplement appeler une autre des méthodes plot sur cet objet axes.
fig, ax = plt.subplots(figsize=(8, 8))
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
# Add a vertical line, here we set the style in the function call
ax.axvline(group_mean, ls='--', color='r')
# Annotate new companies
for group in [3, 5, 8]:
ax.text(145000, group, "New Company", fontsize=10,
verticalalignment="center")
# Now we move our title up since it's getting a little cramped
ax.title.set(y=1.05)
ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',
title='Company Revenue')
ax.xaxis.set_major_formatter(currency)
ax.set_xticks([0, 25e3, 50e3, 75e3, 100e3, 125e3])
fig.subplots_adjust(right=.1)
plt.show()
Sauver notre parcelle #
Maintenant que nous sommes satisfaits du résultat de notre intrigue, nous voulons l'enregistrer sur le disque. Il existe de nombreux formats de fichiers dans lesquels nous pouvons enregistrer dans Matplotlib. Pour voir une liste des options disponibles, utilisez :
print(fig.canvas.get_supported_filetypes())
{'eps': 'Encapsulated Postscript', 'jpg': 'Joint Photographic Experts Group', 'jpeg': 'Joint Photographic Experts Group', 'pdf': 'Portable Document Format', 'pgf': 'PGF code for LaTeX', 'png': 'Portable Network Graphics', 'ps': 'Postscript', 'raw': 'Raw RGBA bitmap', 'rgba': 'Raw RGBA bitmap', 'svg': 'Scalable Vector Graphics', 'svgz': 'Scalable Vector Graphics', 'tif': 'Tagged Image File Format', 'tiff': 'Tagged Image File Format', 'webp': 'WebP Image Format'}
Nous pouvons ensuite utiliser le figure.Figure.savefig()
afin de sauvegarder la figure sur le disque. Notez qu'il existe plusieurs drapeaux utiles que nous montrons ci-dessous :
transparent=True
rend transparent l'arrière-plan de la figure enregistrée si le format le permet.dpi=80
contrôle la résolution (points par pouce carré) de la sortie.bbox_inches="tight"
adapte les limites de la figure à notre intrigue.
# Uncomment this line to save the figure.
# fig.savefig('sales.png', transparent=False, dpi=80, bbox_inches="tight")
Durée totale d'exécution du script : (0 minutes 3,918 secondes)