HOWTO · Matplotlib

Crea una singola legenda per tutte le sottotrame in Matplotlib

Con `fig.legend()` puoi associare una legenda all’intera figura Matplotlib, mentre `ax.legend()` crea una legenda per un singolo Axes. Se tutti i subplot mostrano le stesse serie con le stesse etichette, puoi riutilizzare gli handle e le etichette di un Axes; se il contenuto differisce, raccogli quelli di ogni Axes.

In questa pagina

Usa fig.legend() per associare una sola legenda all’intera figura Matplotlib. Se tutti i subplot mostrano le stesse serie con le stesse etichette, puoi riutilizzare gli handle e le etichette di un Axes. Se invece i subplot mostrano serie diverse, raccogli gli handle e le etichette di ogni Axes e passa entrambe le liste alla legenda della figura. ax.legend() crea invece una legenda per un singolo Axes.

Gli esempi seguenti usano Matplotlib per creare le figure. Il primo stampa anche le etichette raccolte per la legenda condivisa. Le etichette mostrate negli esempi e nell’output restano in inglese, come nel codice originale.

Crea una legenda condivisa a livello di figura quando i subplot usano le stesse etichette

Se ogni subplot traccia le stesse serie con le stesse etichette, basta un solo subplot per ottenere le voci necessarie alla legenda condivisa. L’esempio seguente usa due misurazioni con scale diverse, entrambe etichettate measurement. Poiché l’etichetta e il significato coincidono, è sufficiente recuperare gli handle dal primo Axes. Associa la legenda a fig, invece di chiamare legend() su ciascun Axes, per mostrarla una sola volta nell’intera figura.

Esegui questo esempio:

Il codice e le etichette o gli output visibili in questa sezione restano in inglese.

import matplotlib

matplotlib.use("Agg")
import logging

# Ignore only Matplotlib's benign cold-start cache notice; other diagnostics
# remain visible on stderr.
class _FontCacheNoticeFilter(logging.Filter):
    def filter(self, record):
        return "Matplotlib is building the font cache; this may take a moment." not in record.getMessage()


logging.getLogger("matplotlib.font_manager").addFilter(_FontCacheNoticeFilter())
import matplotlib.pyplot as plt

fig, axes = plt.subplots(2, 1, figsize=(6, 4))
x = [0, 1, 2]

for ax, scale in zip(axes, [1, 2]):
    ax.plot(x, [scale * value for value in x], label="measurement")

handles, labels = axes[0].get_legend_handles_labels()
fig.legend(handles, labels, loc="upper center")
fig.tight_layout(rect=(0, 0, 1, 0.9))
print("Legend entries:", labels)
plt.show()
Legend entries: ['measurement']

get_legend_handles_labels() restituisce due liste abbinate per gli elementi con etichetta presenti in quell’Axes. Il metodo con etichette condivise è conciso, ma rappresenta solo le serie presenti nell’Axes scelto. Se un altro subplot contiene un’etichetta o una serie diversa, usa il metodo che raccoglie i dati da tutti gli Axes, illustrato nella sezione successiva.

Raccogli handle ed etichette da ogni Axes quando il contenuto dei subplot è diverso

Quando i subplot contengono linee con etichette diverse, raccogli gli handle e le etichette di ciascun Axes nello stesso ciclo. Le liste restano abbinate in base alla posizione: l’handle all’indice i corrisponde all’etichetta all’indice i. Il codice seguente produce due voci nella legenda, una per ogni linea.

Esegui questo esempio:

Il codice e le etichette o gli output visibili in questa sezione restano in inglese.

import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 2, figsize=(7, 3))
axes[0].plot([0, 1, 2], [0, 1, 4], label="quadratic")
axes[1].plot([0, 1, 2], [0, 1, 2], label="linear")

handles, labels = [], []
for ax in axes:
    ax_handles, ax_labels = ax.get_legend_handles_labels()
    handles.extend(ax_handles)
    labels.extend(ax_labels)

fig.legend(handles, labels, loc="upper center", ncol=2)
fig.tight_layout(rect=(0, 0, 1, 0.88))
plt.show()

Il ciclo raccoglie gli elementi con etichetta da ogni Axes, quindi le etichette ripetute possono comparire più volte. Se le voci duplicate rappresentano lo stesso concetto, seleziona un handle per ciascuna etichetta desiderata prima di chiamare fig.legend(). Mantieni invece etichette distinte quando servono a differenziare le serie. Se vuoi mostrare solo alcune linee, passa gli handle e le etichette corrispondenti: la legenda non deve includere ogni linea tracciata.

Posiziona e formatta la legenda a livello di figura

L’argomento loc sceglie quale punto della legenda allineare al punto di ancoraggio. Per esempio, fig.legend(..., loc="upper center") centra la legenda nella parte superiore della figura. Per controllare esplicitamente l’ancoraggio, usa bbox_to_anchor; per una legenda della figura, le coordinate sono relative alla figura stessa. Per esempio, fig.legend(handles, labels, loc="upper center", bbox_to_anchor=(0.5, 1.02)) posiziona la legenda appena sopra il bordo superiore. Modifica i valori di ancoraggio per spostarla e riserva spazio con fig.tight_layout(rect=(0, 0, 1, 0.9)) oppure fig.subplots_adjust(top=0.82), così non coprirà il contenuto dei subplot.

Per lo stile della legenda puoi usare le stesse opzioni comuni alle altre legende Matplotlib. Passa a fig.legend() valori come fontsize=9, frameon=False o facecolor="white" per modificare la dimensione del testo, la cornice o lo sfondo. Quando salvi una figura con una legenda fuori dai suoi limiti, fig.savefig("plot.png", bbox_inches="tight") può includere la legenda esterna nell’immagine salvata.

Domande frequenti sulla legenda a livello di figura

Qual è la differenza tra ax.legend() e fig.legend()? ax.legend() appartiene a un Axes specifico. fig.legend() appartiene alla Figure e può combinare le voci fornite da uno o più Axes.

Come posso creare un’unica legenda quando tutti i subplot usano le stesse etichette? Recupera gli handle e le etichette da un Axes rappresentativo, quindi passali a fig.legend(). Il metodo funziona se quell’Axes contiene le stesse serie etichettate degli altri subplot.

Come includo solo alcune linee? Mantieni gli handle e le etichette desiderati in liste abbinate e passale a fig.legend(). Se le etichette si ripetono, verifica se le voci rappresentano la stessa serie prima di rimuovere i duplicati.

Come evito di coprire i grafici? Posiziona la legenda nel margine della figura con loc e bbox_to_anchor, quindi riserva spazio nel layout dei subplot. Se la legenda si trova fuori dalla tela, quando salvi usa un riquadro di delimitazione stretto per evitare che venga tagliata.