¿Cuándo usar cla (), clf () o close () para borrar un gráfico en matplotlib?

542

Matplotlib ofrece sus funciones:

cla()   # Clear axis
clf()   # Clear figure
close() # Close a figure window

La documentación no ofrece mucha información sobre cuál es la diferencia entre estas funciones. ¿Cuándo debo usar cada función y qué hace exactamente?

southoz
fuente

Respuestas:

714

Todos hacen cosas diferentes, ya que matplotlib usa un orden jerárquico en el que una ventana de figura contiene una figura que puede constar de muchos ejes. Además, hay funciones de la interfaz de pyplot y hay métodos en la Figureclase. Discutiré ambos casos a continuación.

interfaz de pyplot

pyplotes un módulo que recopila un par de funciones que permiten utilizar matplotlib de manera funcional. Supongo que pyplotse ha importado como import matplotlib.pyplot as plt. En este caso, hay tres comandos diferentes que eliminan cosas:

plt.cla()borra los ejes , es decir, los ejes actualmente activos en la figura actual. Deja los otros ejes intactos.

plt.clf()borra toda la figura actual con todos sus ejes, pero deja la ventana abierta, de modo que puede reutilizarse para otros trazados.

plt.close()cierra una ventana , que será la ventana actual, si no se especifica lo contrario.

Las funciones que más le convengan dependen de su caso de uso.

La close()función además permite especificar qué ventana debe cerrarse. El argumento puede ser un número o un nombre dado a una ventana cuando se creó usando figure(number_or_name)o puede ser una instancia de figura figobtenida, es decir, usando fig = figure(). Si no se da ningún argumento close(), la ventana activa actualmente se cerrará. Además, existe la sintaxis close('all'), que cierra todas las figuras.

métodos de la clase Figura

Además, la Figureclase proporciona métodos para borrar cifras. Asumiré a continuación que figes una instancia de a Figure:

fig.clf()borra toda la figura . Esta llamada es equivalente a plt.clf()solo si figes la cifra actual.

fig.clear() es sinónimo de fig.clf()

Tenga en cuenta que incluso del figno cerrará la ventana de figura asociada. Hasta donde sé, la única forma de cerrar una ventana de figura es usar plt.close(fig)como se describe anteriormente.

David Zwicker
fuente
38
Debido a que close()es un comando no específico, busqué una forma de especificar el cierre de la figura ( fig.close()no es una función). La sintaxis correcta es: plt.close(fig).
tyleha
¿Qué pasa? clear()No he visto mucha diferencia con cla()solo que en los ejes de parásitos solo cla()se trata especialmente.
guión
1
No hay ninguna clear()función en mi matplotlib.pyplot(Versión 1.4.2 en MacOS). ¿Podría dirigirme a la documentación asociada?
David Zwicker
2
Tanto la clase Figure como Axes tienen un clear()método. El Figure.clearequivalente a clfy Axes.cleares equivalente a cla.
SiggyF
2
¿Funciona esto con respecto a Jupyter? Sigo golpeando errores de memoria porque las cifras no se están recogiendo cuando vuelvo a ejecutar una celda en Jupyter.
CMCDragonkai
79

Solo hay una advertencia que descubrí hoy. Si tiene una función que está llamando a una trama muchas veces, es mejor usarla en plt.close(fig)lugar de fig.clf()alguna manera, la primera no se acumula en la memoria. En resumen, si la memoria es una preocupación, use plt.close (fig) (aunque parece que hay mejores formas, vaya al final de este comentario para obtener enlaces relevantes).

Entonces el siguiente script producirá una lista vacía:

for i in range(5):
    fig = plot_figure()
    plt.close(fig)
# This returns a list with all figure numbers available
print(plt.get_fignums())

Mientras que este producirá una lista con cinco cifras.

for i in range(5):
    fig = plot_figure()
    fig.clf()
# This returns a list with all figure numbers available
print(plt.get_fignums())

De la documentación anterior no me queda claro cuál es la diferencia entre cerrar una figura y cerrar una ventana. Quizás eso aclare.

Si quieres probar un script completo, tienes:

import numpy as np
import matplotlib.pyplot as plt
x = np.arange(1000)
y = np.sin(x)

for i in range(5):
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.plot(x, y)
    plt.close(fig)

print(plt.get_fignums())

for i in range(5):
    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1)
    ax.plot(x, y)
    fig.clf()

print(plt.get_fignums())

Si la memoria es una preocupación, alguien ya publicó una solución alternativa en SO, vea: Cree una figura que se cuente por referencia

Ramon Martinez
fuente
26
Gracias por la útil referencia cruzada a la pregunta de conteo de referencias. Así es exactamente como Matplotlib ya debería funcionar. Es igualmente aterrador y atroz que las cifras nunca sean basura recolectada bajo la pyplotAPI estándar .
Cecil Curry
1
Sin embargo, he descubierto que si uno tiene que hacer animaciones (por ejemplo, algunos mapas de contorno 2D / pcolormesh) es mejor borrar la figura y dibujar nuevos campos en lugar de cerrar viejos y hacer nuevos paneles de figuras. La velocidad será completamente diferente.
msi_gerva