Il ciclo di vita di un complotto #

Questo tutorial ha lo scopo di mostrare l'inizio, la parte centrale e la fine di una singola visualizzazione utilizzando Matplotlib. Inizieremo con alcuni dati grezzi e finiremo salvando una figura di una visualizzazione personalizzata. Lungo la strada proviamo a evidenziare alcune caratteristiche e best practice chiare utilizzando Matplotlib.

Nota

Questo tutorial è basato su questo eccellente post sul blog di Chris Moffitt. È stato trasformato in questo tutorial da Chris Holdgraf.

Una nota sulle interfacce esplicite e implicite #

Matplotlib ha due interfacce. Per una spiegazione dei compromessi tra le interfacce esplicite e implicite, vedere Matplotlib Application Interfaces (APIs) .

Nell'interfaccia esplicita orientata agli oggetti (OO) utilizziamo direttamente le istanze di axes.Axesper creare la visualizzazione in un'istanza di figure.Figure. Nell'interfaccia implicita, ispirata e modellata su MATLAB, utilizza un'interfaccia basata sullo stato globale che è incapsulata nel pyplotmodulo per tracciare gli "assi correnti". Guarda i tutorial su pyplot per uno sguardo più approfondito all'interfaccia di pyplot.

La maggior parte dei termini è semplice, ma la cosa principale da ricordare è che:

  • La figura è l'immagine finale che può contenere 1 o più assi.

  • Gli assi rappresentano un grafico individuale (non confonderlo con la parola "asse", che si riferisce all'asse x/y di un grafico).

Chiamiamo metodi che eseguono il tracciato direttamente dagli assi, il che ci offre molta più flessibilità e potenza nella personalizzazione della nostra trama.

Nota

In generale preferiscono l'interfaccia esplicita rispetto all'interfaccia pyplot implicita per la stampa.

I nostri dati #

Useremo i dati del post da cui è stato derivato questo tutorial. Contiene informazioni sulle vendite per un certo numero di aziende.

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)

Per iniziare #

Questi dati vengono naturalmente visualizzati come un grafico a barre, con una barra per gruppo. Per fare ciò con l'approccio orientato agli oggetti, prima generiamo un'istanza di figure.Figuree axes.Axes. La figura è come una tela e gli assi sono una parte di quella tela su cui faremo una visualizzazione particolare.

Nota

Le figure possono avere più assi su di esse. Per informazioni su come eseguire questa operazione, vedere l' esercitazione Tight Layout .

fig, ax = plt.subplots()
ciclo vitale

Ora che abbiamo un'istanza di Axes, possiamo tracciarci sopra.

ciclo vitale
<BarContainer object of 10 artists>

Controllare lo stile #

Ci sono molti stili disponibili in Matplotlib per permetterti di adattare la tua visualizzazione alle tue esigenze. Per vedere un elenco di stili, possiamo usare 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']

Puoi attivare uno stile con quanto segue:

plt.style.use('fivethirtyeight')

Ora rifacciamo la trama sopra per vedere come appare:

ciclo vitale
<BarContainer object of 10 artists>

Lo stile controlla molte cose, come colore, larghezza di riga, sfondo, ecc.

Personalizzare la trama #

Ora abbiamo una trama con l'aspetto generale che vogliamo, quindi perfezioniamola in modo che sia pronta per la stampa. Per prima cosa ruotiamo le etichette sull'asse x in modo che vengano visualizzate più chiaramente. Possiamo accedere a queste etichette con il axes.Axes.get_xticklabels()metodo:

ciclo vitale

Se desideriamo impostare la proprietà di più elementi contemporaneamente, è utile utilizzare la pyplot.setp()funzione. Questo richiederà un elenco (o molti elenchi) di oggetti Matplotlib e tenterà di impostare alcuni elementi di stile di ciascuno.

fig, ax = plt.subplots()
ax.barh(group_names, group_data)
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, horizontalalignment='right')
ciclo vitale
[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]

Sembra che questo abbia tagliato alcune delle etichette sul fondo. Possiamo dire a Matplotlib di fare automaticamente spazio agli elementi nelle figure che creiamo. Per fare questo impostiamo il autolayoutvalore del nostro rcParams. Per ulteriori informazioni sul controllo dello stile, del layout e di altre funzionalità dei grafici con rcParams, vedere Personalizzazione di Matplotlib con fogli di stile e 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')
ciclo vitale
[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]

Successivamente, aggiungiamo etichette alla trama. Per fare ciò con l'interfaccia OO, possiamo usare il Artist.set()metodo per impostare le proprietà di questo oggetto 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')
Entrate aziendali
[(-10000.0, 140000.0), Text(0.5, 87.00000000000003, 'Total Revenue'), Text(86.99999999999997, 0.5, 'Company'), Text(0.5, 1.0, 'Company Revenue')]

Possiamo anche regolare la dimensione di questo grafico usando la pyplot.subplots() funzione. Possiamo farlo con l' argomento della parola chiave figsize .

Nota

Mentre l'indicizzazione in NumPy segue la forma (riga, colonna), l' argomento della parola chiave figsize segue la forma (larghezza, altezza). Ciò segue le convenzioni della visualizzazione, che purtroppo sono diverse da quelle dell'algebra lineare.

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')
Entrate aziendali
[(-10000.0, 140000.0), Text(0.5, 86.99999999999997, 'Total Revenue'), Text(86.99999999999997, 0.5, 'Company'), Text(0.5, 1.0, 'Company Revenue')]

Per le etichette, possiamo specificare linee guida di formattazione personalizzate sotto forma di funzioni. Di seguito definiamo una funzione che accetta un numero intero come input e restituisce una stringa come output. Se usati con Axis.set_major_formattero Axis.set_minor_formatter, creeranno e useranno automaticamente una ticker.FuncFormatterclasse.

Per questa funzione, l' xargomento è l'etichetta del segno di spunta originale ed pos è la posizione del segno di spunta. Useremo solo xqui, ma sono necessari entrambi gli argomenti.

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

Possiamo quindi applicare questa funzione alle etichette sul nostro grafico. Per fare questo, usiamo l' xaxisattributo dei nostri assi. Ciò ti consente di eseguire azioni su un asse specifico sulla nostra trama.

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)
Entrate aziendali

Combinazione di più visualizzazioni #

È possibile disegnare più elementi di trama sulla stessa istanza di axes.Axes. Per fare questo abbiamo semplicemente bisogno di chiamare un altro dei metodi plot su quell'oggetto axis.

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()
Entrate aziendali

Salvare la nostra trama #

Ora che siamo soddisfatti del risultato della nostra trama, vogliamo salvarla su disco. Ci sono molti formati di file che possiamo salvare in Matplotlib. Per visualizzare un elenco delle opzioni disponibili, utilizzare:

{'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'}

Possiamo quindi utilizzare il figure.Figure.savefig()per salvare la figura su disco. Nota che ci sono diversi flag utili che mostriamo di seguito:

  • transparent=Truerende trasparente lo sfondo della figura salvata se il formato lo supporta.

  • dpi=80controlla la risoluzione (punti per pollice quadrato) dell'output.

  • bbox_inches="tight"adatta i limiti della figura alla nostra trama.

# Uncomment this line to save the figure.
# fig.savefig('sales.png', transparent=False, dpi=80, bbox_inches="tight")

Tempo di esecuzione totale dello script: (0 minuti 3,918 secondi)

Galleria generata da Sphinx-Gallery