HOWTO · Matplotlib
Diferencias entre cla(), clf() y close() en Matplotlib
Aprende a elegir entre matplotlib.pyplot.cla(), que limpia los Axes actuales; matplotlib.pyplot.clf(), que limpia la Figure actual; y matplotlib.pyplot.close(), que cierra una Figure. Son funciones de pyplot, no métodos.
En esta página
Elige la función según el objeto sobre el que quieres actuar: matplotlib.pyplot.cla() limpia los Axes actuales, matplotlib.pyplot.clf() limpia la Figure actual y matplotlib.pyplot.close() cierra una Figure. Son funciones de pyplot, no métodos, y cada una opera en un ámbito distinto. Usa cla() para redibujar un subgráfico, clf() para reutilizar una Figure con un diseño nuevo y close() cuando hayas terminado con una Figure.
La diferencia de un vistazo
Las tres funciones forman una jerarquía de ámbitos. cla() trabaja sobre la unidad más pequeña, un único Axes. clf() trabaja sobre toda la Figure que contiene ese Axes. close() va un paso más allá y elimina la Figure de pyplot por completo.
| Función | Actúa sobre | Elimina | Qué sobrevive |
|---|---|---|---|
plt.cla() |
Los Axes actuales | Datos trazados, etiquetas, título, leyenda y demás contenido de los Axes | Los propios Axes, su posición en el diseño, todos los Axes vecinos y la Figure |
plt.clf() |
La Figure actual | Todos los Axes de la Figure y su contenido | El objeto Figure y su ventana, listos para recibir nuevos Axes |
plt.close() |
Una Figure gestionada por pyplot | El registro de la Figure en pyplot (y su ventana en los backends interactivos) | Nada de esa Figure dentro de pyplot; las Figures vecinas no se ven afectadas |
El ámbito importa sobre todo cuando una Figure contiene varios subgráficos. Limpiar unos Axes los mantiene en el diseño, de modo que su posición y los demás subgráficos siguen disponibles. Limpiar una Figure elimina todos sus Axes a la vez, pero deja la Figure disponible para nuevos Axes y gráficos. Cerrar una Figure pone fin a la gestión que pyplot hace de ella, y es la única de las tres que libera los recursos de la Figure.
Las tres funciones de pyplot actúan sobre los Axes o la Figure actuales, a menos que selecciones antes un destino. Si ya tienes un objeto Axes o Figure, las operaciones a nivel de objeto ax.clear() y fig.clear() hacen explícito el destino, en lugar de depender de qué Axes o Figure sea el actual. En el caso de close(), puedes pasar la Figure directamente, como en plt.close(fig).
matplotlib.pyplot.cla()
cla() limpia los datos trazados, las etiquetas de los ejes, el título, la leyenda y el resto del contenido de los Axes actuales. Los propios Axes permanecen en la Figure, en su posición original, de modo que una cuadrícula de subgráficos conserva su diseño y cada subgráfico vecino conserva su gráfico. Limpiar unos Axes no los elimina de fig.axes ni cambia las posiciones de sus vecinos.
Esto convierte a cla() en la herramienta adecuada para un bucle de actualización: selecciona los Axes, limpia su contenido y dibuja los datos nuevos en el mismo lugar. Es el patrón que hay detrás de las animaciones sencillas y de los paneles que actualizan una sola zona mientras el resto de la Figure queda intacto.
El ejemplo siguiente crea dos subgráficos y después limpia solo el segundo. Las comprobaciones impresas muestran que la Figure sigue conteniendo ambos Axes, que el primer Axes conserva su línea y que el segundo Axes no tiene líneas y tiene el título vacío.
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)
Salida:
axes=2; ax1_lines=1; ax2_lines=0; ax2_title=''
Antes de la llamada, ambos subgráficos contienen una curva:
Después de plt.cla(), el segundo Axes está vacío pero sigue ocupando su sitio, y el primer subgráfico no ha cambiado:
Elige cla() cuando la disposición de los subgráficos debe mantenerse y solo debe actualizarse el contenido de unos Axes. Si tu código ya tiene la variable de los Axes, ax.clear() expresa la misma intención a nivel de Axes sin cambiar la selección de Axes actuales de pyplot.
matplotlib.pyplot.clf()
matplotlib.pyplot.clf() limpia la Figure actual, incluidos todos sus Axes y su contenido. Deja el objeto Figure disponible para reutilizarlo y no cierra el gestor de Figure asociado, de modo que la misma Figure — y, en una sesión interactiva, la misma ventana — puede volver a llenarse desde cero. No existe una operación clf() por Axes, porque esta función trabaja a nivel de Figure.
Después de clf(), la Figure no tiene ningún Axes, así que debes crear nuevos Axes antes de volver a dibujar; una llamada simple a plt.plot() creará implícitamente unos Axes nuevos por ti. Si tienes varias Figures abiertas, selecciona la deseada antes de llamar a plt.clf(); fig.clear() es el equivalente a nivel de objeto y hace explícito el destino.
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)
Salida:
figure_axes=0; figure_open=True
La Figure contiene al principio un gráfico de líneas y un gráfico de barras uno al lado del otro:
La salida confirma que clf() eliminó todos los Axes (figure_axes=0) mientras la propia Figure permaneció abierta (figure_open=True). A continuación, el ejemplo añade unos Axes nuevos y dibuja un gráfico único completamente distinto sobre la misma Figure:
Usa clf() cuando quieras mantener una Figure disponible pero reconstruir desde cero todos sus gráficos o su diseño de subgráficos. Usa cla() en su lugar cuando otros Axes de la misma Figure deban permanecer intactos.
matplotlib.pyplot.close()
matplotlib.pyplot.close() cierra una Figure gestionada por pyplot. Llamada sin argumentos, cierra la Figure actual. Pasa un objeto Figure, su número o un nombre de Figure registrado para dirigirte a una Figure concreta, por ejemplo plt.close(fig), y pasa 'all' para cerrar todas las Figures a la vez.
Cerrar elimina la Figure del registro de pyplot, de modo que plt.fignum_exists() ya no la reporta y pyplot deja de mantener su contenido en memoria. Se diferencia de limpiar en algo importante: después de close() no queda ninguna Figure en pyplot para reutilizar, mientras que después de clf() la misma Figure espera, vacía, nuevo contenido. En los backends interactivos también se destruye la ventana de la Figure, aunque el comportamiento exacto de la ventana visible depende del backend y del contexto de ejecución.
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")
Salida:
open_before=[1, 2]
open_after=[2]; fig1_open=False
Después de la llamada solo sigue registrada la Figure 2, y es la Figure que permanece disponible para mostrarla o guardarla:
Usa close() siempre que crees Figures que ya no necesitas, sobre todo en scripts y bucles que generan muchas Figures. Si necesitas reutilizar la misma Figure, límpiala con clf() en su lugar; si solo hay que actualizar un subgráfico, usa cla() o ax.clear().
Memoria y ciclo de vida de una Figure
Las tres funciones también difieren en lo que cuestan. cla() y clf() son operaciones baratas y repetibles: la Figure sigue registrada en pyplot, su ventana y sus búferes siguen vivos y solo se descarta el contenido. Eso es exactamente lo que quieres para una Figure que se volverá a dibujar. close() es la única que libera la propia Figure, por lo que es el único final correcto para una Figure que no se volverá a dibujar.
pyplot mantiene registrada cada Figure que crea hasta que se cierra explícitamente, y avisa cuando ese registro crece demasiado. Crear Figures en un bucle sin cerrarlas acumula memoria y acaba provocando 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()}")
Salida:
figures_open=25
too_many_figures_warning=True
after_close_all=[]
Ni cla() ni clf() ayudarían en ese bucle, porque el problema es el número de Figures registradas, no su contenido. La regla general es: limpia cuando la misma Figure continúa y cierra cuando no. Los trabajos por lotes que guardan un archivo por Figure deberían llamar a plt.close(fig) inmediatamente después de guardar, para que el pico de memoria se mantenga constante sin importar cuántos informes produzca el trabajo.
¿Qué función debería usar?
- Redibujar un panel de una Figure con varios paneles, como en una animación o un panel en vivo: usa
cla()(oax.clear()), para que el diseño y los demás paneles sobrevivan. - Empezar una Figure desde cero con un diseño distinto manteniendo la misma ventana o el mismo objeto Figure: usa
clf()(ofig.clear()) y después añade Axes nuevos. - Has terminado con una Figure, especialmente dentro de un bucle o un script por lotes: usa
close(), pasando la Figure, su número o'all', para que pyplot la libere.
Los errores más comunes son usar clf() donde se quería cla() — lo que borra en silencio todos los subgráficos de la Figure, no solo el actual —, llamar a cla() mientras los Axes actuales son los equivocados y esperar que una Figure cerrada siga siendo accesible a través de pyplot después. En resumen: limpia unos Axes con cla(), limpia todos los Axes de una Figure con clf() y termina con una Figure usando close().