HOWTO · Matplotlib

Differenze tra le funzioni cla(), clf() e close() in Matplotlib

Scopri le differenze tra matplotlib.pyplot.cla(), che svuota gli Axes correnti, matplotlib.pyplot.clf(), che svuota la Figure corrente, e matplotlib.pyplot.close(), che chiude una Figure.

In questa pagina

Scegli la funzione in base all’oggetto su cui vuoi agire: matplotlib.pyplot.cla() svuota gli Axes correnti, matplotlib.pyplot.clf() svuota la Figure corrente e matplotlib.pyplot.close() chiude una Figure. Sono funzioni di pyplot, non metodi, e ciascuna opera a un livello diverso. Usa cla() per ridisegnare un singolo subplot, clf() per riutilizzare una Figure con un layout nuovo e close() quando hai finito con una Figure.

La differenza a colpo d’occhio

Le tre funzioni formano una gerarchia di ambiti. cla() lavora sull’unità più piccola, un singolo Axes. clf() lavora sull’intera Figure che contiene quell’Axes. close() fa un passo in più e rimuove del tutto la Figure da pyplot.

Funzione Agisce su Rimuove Cosa sopravvive
plt.cla() Gli Axes correnti Dati tracciati, etichette, titolo, legenda e altri contenuti degli Axes Gli Axes stessi, la loro posizione nel layout, tutti gli Axes vicini e la Figure
plt.clf() La Figure corrente Ogni Axes della Figure e il suo contenuto L’oggetto Figure e la sua finestra, pronti a ricevere nuovi Axes
plt.close() Una Figure gestita da pyplot La registrazione della Figure in pyplot (e la sua finestra nei backend interattivi) Niente di quella Figure dentro pyplot; le Figure vicine non sono toccate

L’ambito conta soprattutto quando una Figure contiene più subplot. Svuotare un Axes lo mantiene nel layout, così la sua posizione e gli altri subplot restano disponibili. Svuotare una Figure rimuove tutti i suoi Axes in una volta, lasciando però la Figure disponibile per nuovi Axes e grafici. Chiudere una Figure pone fine alla gestione di pyplot su di essa ed è l’unica delle tre a liberare le risorse della Figure.

Tutte e tre le funzioni di pyplot agiscono sugli Axes o sulla Figure correnti, a meno che tu non selezioni prima una destinazione. Se hai già un oggetto Axes o Figure, le operazioni a livello di oggetto ax.clear() e fig.clear() rendono la destinazione esplicita, invece di affidarti a quali Axes o quale Figure siano correnti. Per close() puoi passare direttamente la Figure, come in plt.close(fig).

matplotlib.pyplot.cla()

cla() svuota i dati tracciati, le etichette degli assi, il titolo, la legenda e gli altri contenuti degli Axes correnti. Gli Axes stessi restano nella Figure, nella posizione originale, così una griglia di subplot conserva il layout e ogni subplot vicino conserva il suo grafico. Svuotare un Axes non lo rimuove da fig.axes e non cambia le posizioni dei suoi vicini.

Questo rende cla() lo strumento giusto per un ciclo di aggiornamento: selezioni gli Axes, ne svuoti il contenuto e tracci i nuovi dati nello stesso spazio. È il modello alla base di animazioni semplici e dashboard che aggiornano un singolo pannello mentre il resto della Figure resta intatto.

L’esempio seguente crea due subplot e poi svuota solo il secondo. I controlli stampati mostrano che la Figure contiene ancora entrambi gli Axes, che il primo Axes ha ancora la sua linea e che il secondo Axes non ha linee e ha il titolo vuoto.

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

x = np.linspace(0, 2 * np.pi, 100)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 3.2))
ax1.plot(x, np.sin(x))
ax1.set_title("Sine (kept)")
ax2.plot(x, np.cos(x), color="orange")
ax2.set_title("Cosine (to be cleared)")
fig.tight_layout()
plt.sca(ax2)
plt.cla()
print(f"axes={len(fig.axes)}; ax1_lines={len(ax1.lines)}; ax2_lines={len(ax2.lines)}; ax2_title={ax2.get_title()!r}")
plt.close(fig)

Produzione:

axes=2; ax1_lines=1; ax2_lines=0; ax2_title=''

Prima della chiamata, entrambi i subplot contengono una curva:

Due subplot prima della chiamata a cla(): una curva seno a sinistra e una curva coseno a destra.

Dopo plt.cla(), il secondo Axes è vuoto ma occupa ancora il suo posto, e il primo subplot è invariato:

Gli stessi due subplot dopo cla(): la curva seno è intatta e il secondo Axes è vuoto ma ancora al suo posto.

Scegli cla() quando la disposizione dei subplot deve restare e deve essere aggiornato solo il contenuto di un Axes. Se il tuo codice ha già la variabile degli Axes, ax.clear() esprime la stessa intenzione a livello di Axes senza cambiare la selezione degli Axes correnti di pyplot.

matplotlib.pyplot.clf()

matplotlib.pyplot.clf() svuota la Figure corrente, inclusi tutti i suoi Axes e il loro contenuto. Lascia l’oggetto Figure disponibile per il riutilizzo e non chiude il gestore di Figure associato, così la stessa Figure — e, in una sessione interattiva, la stessa finestra — può essere riempita di nuovo da zero. Non esiste un’operazione clf() per singolo Axes, perché questa funzione lavora a livello di Figure.

Dopo clf(), la Figure non ha più alcun Axes, quindi devi creare nuovi Axes prima di tracciare di nuovo; una semplice chiamata a plt.plot() creerà implicitamente un nuovo Axes per te. Se hai più Figure aperte, seleziona quella desiderata prima di chiamare plt.clf(); fig.clear() è l’equivalente a livello di oggetto e rende la destinazione esplicita.

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

fig, axes = plt.subplots(1, 2, figsize=(8, 3.2))
axes[0].plot([0, 1, 2], [0, 1, 4])
axes[0].set_title("Line")
axes[1].bar(["A", "B", "C"], [3, 7, 5])
axes[1].set_title("Bar")
fig.tight_layout()
plt.figure(fig.number)
plt.clf()
print(f"figure_axes={len(fig.axes)}; figure_open={plt.fignum_exists(fig.number)}")
ax = fig.add_subplot(1, 1, 1)
ax.plot([0, 1, 2], [4, 1, 0], color="green")
ax.set_title("Rebuilt on the same Figure")
fig.tight_layout()
plt.close(fig)

Produzione:

figure_axes=0; figure_open=True

La Figure contiene all’inizio un grafico a linee e un grafico a barre affiancati:

Una Figure prima della chiamata a clf(), con un grafico a linee e un grafico a barre in due subplot.

L’output conferma che clf() ha rimosso ogni Axes (figure_axes=0) mentre la Figure stessa è rimasta aperta (figure_open=True). L’esempio aggiunge poi un nuovo Axes e disegna un unico grafico completamente diverso sulla stessa Figure:

La stessa Figure dopo clf() e la ricostruzione: un unico nuovo grafico a linee verde riempie l’intera Figure.

Usa clf() quando vuoi mantenere una Figure disponibile ma ricostruire da zero tutti i suoi grafici o il layout dei subplot. Usa invece cla() quando altri Axes nella stessa Figure devono restare intatti.

matplotlib.pyplot.close()

matplotlib.pyplot.close() chiude una Figure gestita da pyplot. Chiamata senza argomenti, chiude la Figure corrente. Passa un oggetto Figure, il suo numero o un nome di Figure registrato per mirare a una Figure particolare, ad esempio plt.close(fig), e passa 'all' per chiudere tutte le Figure in una volta.

Chiudere rimuove la Figure dal registro di pyplot, così plt.fignum_exists() non la segnala più e pyplot non ne mantiene più il contenuto in memoria. Si differenzia dallo svuotamento in un punto importante: dopo close() non resta alcuna Figure in pyplot da riutilizzare, mentre dopo clf() la stessa Figure attende, vuota, nuovi contenuti. Nei backend interattivi viene distrutta anche la finestra della Figure, anche se il comportamento esatto della finestra visibile dipende dal backend e dal contesto di esecuzione.

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

fig1, ax1 = plt.subplots(figsize=(5, 3.2))
ax1.plot([0, 1, 2], [0, 2, 1])
ax1.set_title("Report 1 (to be closed)")
fig1.tight_layout()
fig2, ax2 = plt.subplots(figsize=(5, 3.2))
ax2.plot([0, 1, 2], [1, 0, 3], color="purple")
ax2.set_title("Report 2 (kept open)")
fig2.tight_layout()
print(f"open_before={plt.get_fignums()}")
plt.close(fig1)
print(f"open_after={plt.get_fignums()}; fig1_open={plt.fignum_exists(fig1.number)}")
plt.close("all")

Produzione:

open_before=[1, 2]
open_after=[2]; fig1_open=False

Dopo la chiamata resta registrata solo la Figure 2, ed è la Figure che rimane disponibile per la visualizzazione o il salvataggio:

La seconda Figure sopravvissuta dopo che close() ha rimosso la prima: un unico grafico a linee viola intitolato Report 2.

Usa close() ogni volta che crei Figure che non ti servono più — soprattutto negli script e nei cicli che generano molte Figure. Se devi riutilizzare la stessa Figure, svuotala invece con clf(); se va aggiornato un solo subplot, usa cla() o ax.clear().

Memoria e ciclo di vita di una Figure

Le tre funzioni differiscono anche per il costo. cla() e clf() sono operazioni economiche e ripetibili: la Figure resta registrata in pyplot, la sua finestra e i suoi buffer restano attivi e viene scartato solo il contenuto. È esattamente ciò che serve per una Figure che verrà disegnata di nuovo. close() è l’unica a liberare la Figure stessa, ed è quindi l’unica conclusione corretta per una Figure che non verrà più disegnata.

pyplot mantiene registrata ogni Figure creata finché non viene chiusa esplicitamente, e avvisa quando il registro diventa troppo grande. Creare Figure in un ciclo senza chiuderle accumula memoria e alla fine attiva un RuntimeWarning:

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

with warnings.catch_warnings(record=True) as caught:
    warnings.simplefilter("always")
    for _ in range(25):
        plt.figure()
    print(f"figures_open={len(plt.get_fignums())}")
    print(f"too_many_figures_warning={any(str(w.message).startswith('More than 20 figures') for w in caught)}")
plt.close("all")
print(f"after_close_all={plt.get_fignums()}")

Produzione:

figures_open=25
too_many_figures_warning=True
after_close_all=[]

Né cla() né clf() aiuterebbero in quel ciclo, perché il problema è il numero di Figure registrate, non il loro contenuto. La regola pratica è: svuota quando la stessa Figure continua, chiudi quando non continua. I lavori batch che salvano un file per Figure dovrebbero chiamare plt.close(fig) subito dopo il salvataggio, così il picco di memoria resta costante indipendentemente da quanti report produce il lavoro.

Quale funzione usare?

  • Ridisegnare un pannello di una Figure con più pannelli, come in un’animazione o in una dashboard in tempo reale: usa cla() (o ax.clear()), così layout e altri pannelli sopravvivono.
  • Ricominciare una Figure con un layout diverso mantenendo la stessa finestra o lo stesso oggetto Figure: usa clf() (o fig.clear()), poi aggiungi nuovi Axes.
  • Hai finito con una Figure, specialmente dentro un ciclo o uno script batch: usa close(), passando la Figure, il suo numero o 'all', così pyplot la libera.

Gli errori più comuni sono usare clf() dove era inteso cla() — il che cancella in silenzio ogni subplot della Figure, non solo quello corrente —, chiamare cla() mentre gli Axes correnti sono quelli sbagliati e aspettarsi che una Figure chiusa sia ancora raggiungibile tramite pyplot in seguito. In breve: svuota un Axes con cla(), svuota ogni Axes di una Figure con clf() e concludi con una Figure usando close().