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

text

text

Aggiungi testo in una posizione arbitraria del file Axes.

annotate

annotate

Aggiungi un'annotazione, con una freccia facoltativa, in una posizione arbitraria del file Axes.

xlabel

set_xlabel

Aggiungi un'etichetta Axesall'asse x di .

ylabel

set_ylabel

Aggiungi un'etichetta Axesall'asse y di .

title

set_title

Aggiungi un titolo al file Axes.

figtext

text

Aggiungi testo in una posizione arbitraria del file Figure.

suptitle

suptitle

Aggiungi un titolo al file Figure.

Tutte queste funzioni creano e restituiscono Textun'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()
sottotitolo in grassetto, titolo degli assi

Etichette per l'asse x e y #

Specificare le etichette per l'asse x e y è semplice, tramite i metodi set_xlabele .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()
introduzione testuale

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()
introduzione testuale

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()
introduzione testuale

Oppure, le etichette accettano tutti gli Textargomenti 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()
introduzione testuale

Tutte le etichette in questo tutorial possono essere modificate manipolando il matplotlib.font_manager.FontPropertiesmetodo 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()
introduzione testuale

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()
introduzione testuale

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.

fig, axs = plt.subplots(3, 1, figsize=(5, 6), tight_layout=True)
locs = ['center', 'left', 'right']
for ax, loc in zip(axs, locs):
    ax.plot(x1, y1)
    ax.set_title('Title with loc at '+loc, loc=loc)
plt.show()
Titolo con loc al centro, Titolo con loc a sinistra, Titolo con loc a destra

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()
Titolo sfalsato verticalmente

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.Axisoggetto per ax.xaxise ax.yaxische 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_locatordi Axis.set_minor_locatormetodi che utilizzano i dati tracciati per determinare la posizione dei tick maggiori e minori. Esistono anche Axis.set_major_formattere Axis.set_minor_formattermetodi 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.

fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
axs[1].xaxis.set_ticks(np.arange(0., 8.1, 2.))
plt.show()
introduzione testuale

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()
introduzione testuale

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.StrMethodFormatterpuò anche essere creato passando a strsenza dover creare esplicitamente il formattatore.

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.)
axs[1].xaxis.set_ticks(ticks)
axs[1].xaxis.set_major_formatter('{x:1.1f}')
axs[1].set_xlim(axs[0].get_xlim())
plt.show()
introduzione testuale

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.

fig, axs = plt.subplots(2, 1, figsize=(5, 3), tight_layout=True)
axs[0].plot(x1, y1)
axs[1].plot(x1, y1)
locator = matplotlib.ticker.FixedLocator(ticks)
axs[1].xaxis.set_major_locator(locator)
axs[1].xaxis.set_major_formatter({x}°')
plt.show()
introduzione testuale

Il formattatore predefinito è matplotlib.ticker.MaxNLocatorchiamato 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=autoutilizza un algoritmo per determinare quanti tick saranno accettabili in base alla lunghezza dell'asse. nbins=4La 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()
introduzione testuale

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()
introduzione testuale

Datetick #

Matplotlib può accettare datetime.datetimee 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.datesmodulo.

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()
introduzione testuale

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.DayLocatorclasse, 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()
introduzione testuale

Legende e Annotazioni #

Tempo di esecuzione totale dello script: (0 minuti 5,998 secondi)

Galleria generata da Sphinx-Gallery