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.Axespour 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 pyplotmodule 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.Figureet 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()
cycle de la vie

Maintenant que nous avons une instance Axes, nous pouvons tracer dessus.

cycle de la vie
<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.

['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 :

cycle de la vie
<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 :

cycle de la vie

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')
cycle de la vie
[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 autolayoutvaleur 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')
cycle de la vie
[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')
revenue de l'entreprise
[(-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')
revenue de l'entreprise
[(-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_formatterou Axis.set_minor_formatter, ils créeront et utiliseront automatiquement une ticker.FuncFormatterclasse.

Pour cette fonction, l' xargument est l'étiquette de graduation d'origine et pos la position de la graduation. Nous n'en utiliserons xqu'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' xaxisattribut 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)
revenue de l'entreprise

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()
revenue de l'entreprise

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 :

{'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=Truerend transparent l'arrière-plan de la figure enregistrée si le format le permet.

  • dpi=80contrô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)

Galerie générée par Sphinx-Gallery