Nota
Fare clic qui per scaricare il codice di esempio completo
Testo nei grafici Matplotlib #
Introduzione alla stampa e al lavoro con il testo in Matplotlib.
Matplotlib ha un ampio supporto di testo, incluso il supporto per espressioni matematiche, supporto truetype per output raster e vettoriali, testo separato da nuova riga con rotazioni arbitrarie e supporto Unicode.
Poiché incorpora i caratteri direttamente nei documenti di output, ad esempio per PostScript o PDF, ciò che vedi sullo schermo è ciò che ottieni nella copia cartacea.
Il supporto FreeType produce caratteri con antialias molto carini, che hanno un bell'aspetto anche con raster di piccole dimensioni. Matplotlib include il proprio
(grazie a Paul Barrett), che implementa un
algoritmo di ricerca dei caratteri compatibile con W3Cmatplotlib.font_manager
e multipiattaforma .
L'utente ha un grande controllo sulle proprietà del testo (dimensione del carattere, spessore del carattere, posizione e colore del testo, ecc.) con impostazioni predefinite impostate nel file rc . E significativamente, per coloro che sono interessati a figure matematiche o scientifiche, Matplotlib implementa un gran numero di simboli e comandi matematici TeX, supportando espressioni matematiche ovunque nella tua figura.
Comandi di testo di base #
I seguenti comandi vengono utilizzati per creare testo nelle interfacce implicite ed esplicite (vedere Matplotlib Application Interfaces (API) per una spiegazione dei compromessi):
API implicita |
API esplicita |
descrizione |
---|---|---|
Aggiungi testo in una posizione arbitraria del file |
||
Aggiungi un'annotazione, con una freccia facoltativa, in una posizione arbitraria del file
|
||
Aggiungi un'etichetta
|
||
Aggiungi un'etichetta
|
||
Aggiungi un titolo al file
|
||
Aggiungi testo in una posizione arbitraria del file |
||
Aggiungi un titolo al file |
Tutte queste funzioni creano e restituiscono Text
un'istanza, che può essere configurata con una varietà di caratteri e altre proprietà. L'esempio seguente mostra tutti questi comandi in azione e maggiori dettagli sono forniti nelle sezioni che seguono.
import matplotlib
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot()
fig.subplots_adjust(top=0.85)
# Set titles for the figure and the subplot respectively
fig.suptitle('bold figure suptitle', fontsize=14, fontweight='bold')
ax.set_title('axes title')
ax.set_xlabel('xlabel')
ax.set_ylabel('ylabel')
# Set both x- and y-axis limits to [0, 10] instead of default [0, 1]
ax.axis([0, 10, 0, 10])
ax.text(3, 8, 'boxed italics text in data coords', style='italic',
bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 10})
ax.text(2, 6, r'an equation: $E=mc^2$', fontsize=15)
ax.text(3, 2, 'Unicode: Institut für Festkörperphysik')
ax.text(0.95, 0.01, 'colored text in axes coords',
verticalalignment='bottom', horizontalalignment='right',
transform=ax.transAxes,
color='green', fontsize=15)
ax.plot([2], [1], 'o')
ax.annotate('annotate', xy=(2, 1), xytext=(3, 4),
arrowprops=dict(facecolor='black', shrink=0.05))
plt.show()
Etichette per l'asse x e y #
Specificare le etichette per l'asse x e y è semplice, tramite i
metodi set_xlabel
e .set_ylabel
import matplotlib.pyplot as plt
import numpy as np
x1 = np.linspace(0.0, 5.0, 100)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('time [s]')
ax.set_ylabel('Damped oscillation [V]')
plt.show()
Le etichette x e y vengono posizionate automaticamente in modo da cancellare le etichette x e y. Confronta il grafico sottostante con quello sopra e nota che l'etichetta y è a sinistra di quella sopra.
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1*10000)
ax.set_xlabel('time [s]')
ax.set_ylabel('Damped oscillation [V]')
plt.show()
Se si desidera spostare le etichette, è possibile specificare l' argomento della parola chiave labelpad , dove il valore è punti (1/72", la stessa unità utilizzata per specificare le dimensioni dei caratteri).
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1*10000)
ax.set_xlabel('time [s]')
ax.set_ylabel('Damped oscillation [V]', labelpad=18)
plt.show()
Oppure, le etichette accettano tutti gli Text
argomenti delle parole chiave, incluso
position , tramite il quale possiamo specificare manualmente le posizioni dell'etichetta. Qui inseriamo la xlabel all'estrema sinistra dell'asse. Si noti che la coordinata y di questa posizione non ha alcun effetto: per regolare la posizione y è necessario utilizzare l'
argomento della parola chiave labelpad .
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('time [s]', position=(0., 1e6), horizontalalignment='left')
ax.set_ylabel('Damped oscillation [V]')
plt.show()
Tutte le etichette in questo tutorial possono essere modificate manipolando il
matplotlib.font_manager.FontProperties
metodo o tramite argomenti di parole chiave denominateset_xlabel
from matplotlib.font_manager import FontProperties
font = FontProperties()
font.set_family('serif')
font.set_name('Times New Roman')
font.set_style('italic')
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.15, left=0.2)
ax.plot(x1, y1)
ax.set_xlabel('time [s]', fontsize='large', fontweight='bold')
ax.set_ylabel('Damped oscillation [V]', fontproperties=font)
plt.show()
Infine, possiamo utilizzare il rendering TeX nativo in tutti gli oggetti di testo e avere più righe:
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(bottom=0.2, left=0.2)
ax.plot(x1, np.cumsum(y1**2))
ax.set_xlabel('time [s] \n This was a long experiment')
ax.set_ylabel(r'$\int\ Y^2\ dt\ \ [V^2 s]$')
plt.show()
Titoli #
I titoli delle sottotrame sono impostati più o meno allo stesso modo delle etichette, ma ci sono gli argomenti della parola chiave loc che possono cambiare la posizione e la giustificazione rispetto al valore predefinito di loc=center
.
La spaziatura verticale per i titoli è controllata tramite rcParams["axes.titlepad"]
(predefinito: 6.0
). L'impostazione su un valore diverso sposta il titolo.
fig, ax = plt.subplots(figsize=(5, 3))
fig.subplots_adjust(top=0.8)
ax.plot(x1, y1)
ax.set_title('Vertically offset title', pad=30)
plt.show()
Ticchettii e ticklabel #
Posizionare segni di spunta e etichette di spunta è un aspetto molto complicato della creazione di una figura. Matplotlib fa del suo meglio per eseguire automaticamente l'attività, ma offre anche un framework molto flessibile per determinare le scelte per le posizioni dei tick e il modo in cui sono etichettate.
Terminologia #
Gli assi hanno un matplotlib.axis.Axis
oggetto per ax.xaxis
e
ax.yaxis
che contengono le informazioni su come sono disposte le etichette nell'asse.
L'API dell'asse è spiegata in dettaglio nella documentazione di
axis
.
Un oggetto Axis ha tick maggiori e minori. L'asse dispone
Axis.set_major_locator
di Axis.set_minor_locator
metodi che utilizzano i dati tracciati per determinare la posizione dei tick maggiori e minori. Esistono anche Axis.set_major_formatter
e Axis.set_minor_formatter
metodi che formattano le etichette dei segni di spunta.
Ticchettii semplici #
Spesso è conveniente definire semplicemente i valori dei tick e talvolta le etichette dei tick, sovrascrivendo i localizzatori e i formattatori predefiniti. Questo è sconsigliato perché interrompe la navigazione interattiva della trama. Può anche reimpostare i limiti dell'asse: si noti che il secondo grafico ha i segni di spunta che abbiamo richiesto, inclusi quelli che sono ben al di fuori dei limiti di visualizzazione automatica.
Ovviamente possiamo risolvere questo problema dopo il fatto, ma evidenzia una debolezza dell'hard-coding dei tick. Questo esempio cambia anche il formato dei tick:
fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
ticks = np.arange(0., 8.1, 2.)
# list comprehension to get all tick labels...
tickla = [f'{tick:1.2f}' for tick in ticks]
axs[1].xaxis.set_ticks(ticks)
axs[1].xaxis.set_ticklabels(tickla)
axs[1].set_xlim(axs[0].get_xlim())
plt.show()
Tick Locator e formattatori #
Invece di fare un elenco di tutte le ticklabel, avremmo potuto usare matplotlib.ticker.StrMethodFormatter
(stringa di formato nuovo stile str.format()
) o matplotlib.ticker.FormatStrFormatter
(stringa di formato '%' vecchio stile) e passarlo al file ax.xaxis
. A
matplotlib.ticker.StrMethodFormatter
può anche essere creato passando a
str
senza dover creare esplicitamente il formattatore.
E ovviamente avremmo potuto utilizzare un localizzatore non predefinito per impostare le posizioni dei tick. Nota che passiamo ancora i valori tick, ma la correzione x-limit usata sopra non è necessaria.
Il formattatore predefinito è matplotlib.ticker.MaxNLocator
chiamato as
La parola chiave steps contiene un elenco di multipli che possono essere utilizzati per i valori tick. cioè in questo caso, 2, 4, 6 sarebbero tick accettabili, così come 20, 40, 60 o 0.2, 0.4, 0.6. Tuttavia, 3, 6, 9 non sarebbero accettabili perché 3 non appare nell'elenco dei passaggi.ticker.MaxNLocator(self, nbins='auto', steps=[1, 2, 2.5, 5, 10])
nbins=auto
utilizza un algoritmo per determinare quanti tick saranno accettabili in base alla lunghezza dell'asse. nbins=4
La dimensione del carattere del ticklabel viene presa in considerazione, ma la lunghezza della stringa tick non lo è (perché non è ancora nota). trama a mano.
fig, axs = plt.subplots(2, 2, figsize=(8, 5), tight_layout=True)
for n, ax in enumerate(axs.flat):
ax.plot(x1*10., y1)
formatter = matplotlib.ticker.FormatStrFormatter('%1.1f')
locator = matplotlib.ticker.MaxNLocator(nbins='auto', steps=[1, 4, 10])
axs[0, 1].xaxis.set_major_locator(locator)
axs[0, 1].xaxis.set_major_formatter(formatter)
formatter = matplotlib.ticker.FormatStrFormatter('%1.5f')
locator = matplotlib.ticker.AutoLocator()
axs[1, 0].xaxis.set_major_formatter(formatter)
axs[1, 0].xaxis.set_major_locator(locator)
formatter = matplotlib.ticker.FormatStrFormatter('%1.5f')
locator = matplotlib.ticker.MaxNLocator(nbins=4)
axs[1, 1].xaxis.set_major_formatter(formatter)
axs[1, 1].xaxis.set_major_locator(locator)
plt.show()
Infine, possiamo specificare le funzioni per il formattatore usando
matplotlib.ticker.FuncFormatter
. Inoltre, come
matplotlib.ticker.StrMethodFormatter
, il passaggio di una funzione creerà automaticamente un file matplotlib.ticker.FuncFormatter
.
def formatoddticks(x, pos):
"""Format odd tick positions."""
if x % 2:
return f'{x:1.2f}'
else:
return ''
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.plot(x1, y1)
locator = matplotlib.ticker.MaxNLocator(nbins=6)
ax.xaxis.set_major_formatter(formatoddticks)
ax.xaxis.set_major_locator(locator)
plt.show()
Datetick #
Matplotlib può accettare datetime.datetime
e numpy.datetime64
oggetti come argomenti di tracciamento. Date e orari richiedono una formattazione speciale, che spesso può trarre vantaggio dall'intervento manuale. Per aiutare, le date hanno localizzatori e formattatori speciali, definiti nel matplotlib.dates
modulo.
Un semplice esempio è il seguente. Nota come dobbiamo ruotare le etichette dei segni di spunta in modo che non si sovrappongano a vicenda.
import datetime
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
base = datetime.datetime(2017, 1, 1, 0, 0, 1)
time = [base + datetime.timedelta(days=x) for x in range(len(x1))]
ax.plot(time, y1)
ax.tick_params(axis='x', rotation=70)
plt.show()
Possiamo passare un formato a matplotlib.dates.DateFormatter
. Si noti inoltre che il 29 e il mese successivo sono molto vicini tra loro. Possiamo risolvere questo problema utilizzando la dates.DayLocator
classe, che ci consente di specificare un elenco di giorni del mese da utilizzare. Formattatori simili sono elencati nel matplotlib.dates
modulo.
import matplotlib.dates as mdates
locator = mdates.DayLocator(bymonthday=[1, 15])
formatter = mdates.DateFormatter('%b %d')
fig, ax = plt.subplots(figsize=(5, 3), tight_layout=True)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)
ax.plot(time, y1)
ax.tick_params(axis='x', rotation=70)
plt.show()
Legende e Annotazioni #
Leggende: guida alle leggende
Annotazioni: annotazioni
Tempo di esecuzione totale dello script: (0 minuti 5,998 secondi)