Quand utiliser cla (), clf () ou close () pour effacer un tracé dans matplotlib?

542

Matplotlib propose ses fonctions:

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

La documentation n'offre pas beaucoup d'informations sur la différence entre ces fonctions. Quand dois-je utiliser chaque fonction et que fait-elle exactement?

Southoz
la source

Réponses:

714

Ils font tous des choses différentes, car matplotlib utilise un ordre hiérarchique dans lequel une fenêtre de figure contient une figure qui peut être composée de plusieurs axes. De plus, il existe des fonctions de l'interface pyplot et il existe des méthodes sur leFigure classe. Je vais discuter des deux cas ci-dessous.

interface pyplot

pyplotest un module qui rassemble quelques fonctions qui permettent d'utiliser matplotlib de manière fonctionnelle. Je suppose ici que cela pyplota été importé en tant que import matplotlib.pyplot as plt. Dans ce cas, il existe trois commandes différentes qui suppriment les éléments:

plt.cla()efface un axe , c'est-à-dire les axes actuellement actifs dans la figure actuelle. Il laisse les autres axes intacts.

plt.clf()efface la figure actuelle entière avec tous ses axes, mais laisse la fenêtre ouverte, de sorte qu'elle peut être réutilisée pour d'autres tracés.

plt.close()ferme une fenêtre , qui sera la fenêtre actuelle, sauf indication contraire.

La fonction qui vous convient le mieux dépend donc de votre cas d'utilisation.

La close()fonction permet en outre de spécifier quelle fenêtre doit être fermée. L'argument peut être soit un nombre ou un nom donné à une fenêtre lors de sa création en utilisant, figure(number_or_name)soit une instance de figure figobtenue, c'est-à-dire en utilisant fig = figure(). Si aucun argument n'est donné close(), la fenêtre actuellement active sera fermée. De plus, il y a la syntaxe close('all'), qui ferme toutes les figures.

méthodes de la classe Figure

De plus, la Figureclasse fournit des méthodes pour effacer les chiffres. Je suppose que dans ce qui suit figest une instance de Figure:

fig.clf()efface la figure entière . Cet appel est équivalent à plt.clf()seulement si figest le chiffre actuel.

fig.clear() est synonyme de fig.clf()

Notez que même del figne fermera pas la fenêtre de figure associée. Pour autant que je sache, la seule façon de fermer une fenêtre de figure est d'utiliser plt.close(fig)comme décrit ci-dessus.

David Zwicker
la source
38
Parce que close()c'est une commande non spécifique, je suis allé chercher un moyen de spécifier la fermeture de la figure (ce fig.close()n'est pas une fonction). La syntaxe correcte est: plt.close(fig).
tyleha
qu'en est-il clear(), je n'ai pas vu beaucoup de différence avec cla()seulement que dans les axes parasites seulement cla()est traité spécialement.
dashesy
1
Il n'y a pas de clear()fonction dans mon matplotlib.pyplot(version 1.4.2 sur MacOS). Pourriez-vous me diriger vers la documentation associée?
David Zwicker
2
La classe Figure et la classe Axes ont toutes deux une clear()méthode. L' Figure.clearéquivalent de clfet Axes.clearest équivalent à cla.
SiggyF
2
Est-ce que cela fonctionne en ce qui concerne jupyter? Je continue de frapper des erreurs de mémoire car les chiffres ne sont pas récupérés lorsque je réexécute une cellule dans jupyter.
CMCDragonkai
79

Il y a juste une mise en garde que j'ai découverte aujourd'hui. Si vous avez une fonction qui appelle un tracé un grand nombre de fois, il vaut mieux l'utiliser plt.close(fig)plutôt que fig.clf()la première ne s'accumule pas en mémoire. En bref, si la mémoire est un problème, utilisez plt.close (fig) (bien qu'il semble qu'il y ait de meilleures façons, allez à la fin de ce commentaire pour les liens pertinents).

Ainsi, le script suivant produira une liste vide:

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

Alors que celui-ci va produire une liste avec cinq chiffres dessus.

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

D'après la documentation ci-dessus, il n'est pas clair pour moi quelle est la différence entre fermer une figure et fermer une fenêtre. Peut-être que cela clarifiera.

Si vous voulez essayer un script complet, vous avez:

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 mémoire est un problème, quelqu'un a déjà publié une solution de contournement dans SO, voir: Créer une figure qui est comptée par référence

Ramon Martinez
la source
26
Merci pour la référence croisée utile à la question de comptage des références. C'est exactement ainsi que Matplotlib devrait déjà fonctionner. Il est tout aussi terrifiant et épouvantable que les chiffres ne soient jamais récupérés sous l' pyplotAPI standard .
Cecil Curry
1
Néanmoins, j'ai trouvé que si l'on doit faire des animations (par exemple certaines cartes 2D de contour / pcolormesh), il est préférable d'effacer la figure et de dessiner de nouveaux champs au lieu de fermer les anciens et de créer de nouveaux panneaux de figure. La vitesse sera complètement différente.
msi_gerva