Quando usar cla (), clf () ou close () para limpar uma plotagem no matplotlib?

542

O Matplotlib oferece funções:

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

A documentação não oferece muitas informações sobre qual é a diferença entre essas funções. Quando devo usar cada função e o que exatamente ela faz?

southoz
fonte

Respostas:

714

Todos eles fazem coisas diferentes, pois o matplotlib usa uma ordem hierárquica na qual uma janela de figura contém uma figura que pode consistir em muitos eixos. Além disso, existem funções da interface pyplot e existem métodos na Figureclasse. Vou discutir os dois casos abaixo.

interface pyplot

pyploté um módulo que coleta algumas funções que permitem que o matplotlib seja usado de maneira funcional. Presumo aqui que pyplottenha sido importado como import matplotlib.pyplot as plt. Nesse caso, existem três comandos diferentes que removem coisas:

plt.cla()limpa os eixos , ou seja, os eixos atualmente ativos na figura atual. Deixa os outros eixos intocados.

plt.clf()limpa a figura atual inteira com todos os seus eixos, mas deixa a janela aberta, para que possa ser reutilizada em outras parcelas.

plt.close()fecha uma janela , que será a janela atual, se não for especificado de outra forma.

Quais funções melhor se adequam a você dependem, portanto, do seu caso de uso.

Além close()disso, a função permite especificar qual janela deve ser fechada. O argumento pode ser um número ou nome dado a uma janela quando foi criada usando figure(number_or_name)ou pode ser uma instância de figura figobtida, ou seja, usando fig = figure(). Se nenhum argumento for fornecido close(), a janela atualmente ativa será fechada. Além disso, existe a sintaxe close('all'), que fecha todas as figuras.

métodos da classe Figura

Além disso, a Figureclasse fornece métodos para limpar números. Assumirei a seguir que figé uma instância de um Figure:

fig.clf()limpa a figura inteira . Essa chamada é equivalente plt.clf()apenas se figfor o valor atual.

fig.clear() é sinônimo de fig.clf()

Observe que even del fignão fecha a janela da figura associada. Tanto quanto sei, a única maneira de fechar uma janela de figura é usando plt.close(fig)como descrito acima.

David Zwicker
fonte
38
Por close()ser um comando não específico, procurei uma maneira de especificar o fechamento da figura ( fig.close()não é uma função). A sintaxe correta é: plt.close(fig).
tyleha
que tal clear(), eu não vi muita diferença cla()apenas com o fato de que apenas nos eixos parasitas cla()são tratados especialmente.
dashesy
1
Não há nenhuma clear()função no meu matplotlib.pyplot(Versão 1.4.2 no MacOS). Você poderia me direcionar para a documentação associada?
21714 David Zwicker
2
As classes Figura e Eixos têm um clear()método. O Figure.clearequivalente a clfe Axes.clearé equivalente a cla.
SiggyF 26/09
2
Isso funciona com relação ao jupyter? Eu continuo encontrando erros de memória porque os números não estão sendo coletados como lixo quando executo uma célula no jupyter.
precisa saber é o seguinte
79

Há apenas uma ressalva que eu descobri hoje. Se você tem uma função que está chamando uma plotagem muitas vezes, é melhor usar, em plt.close(fig)vez de, de fig.clf()alguma forma, a primeira não se acumular na memória. Em resumo, se a memória é uma preocupação, use plt.close (fig.) (Embora pareça que existem maneiras melhores, vá para o final deste comentário para obter links relevantes).

Portanto, o seguinte script produzirá uma lista vazia:

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

Considerando que este irá produzir uma lista com cinco figuras.

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

Na documentação acima, não está claro qual é a diferença entre fechar uma figura e fechar uma janela. Talvez isso esclareça.

Se você quiser tentar um script completo, você tem:

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())

Se a memória é uma preocupação, alguém já postou uma solução alternativa no SO, consulte: Crie uma figura com referência contada

Ramon Martinez
fonte
26
Obrigado pela referência cruzada útil para a pergunta de contagem de referência. É exatamente assim que o Matplotlib já deve funcionar. É igualmente assustador e assustador que os números nunca sejam coletados como lixo sob a pyplotAPI padrão .
perfil completo de Cecil Curry
1
No entanto, descobri que se é necessário fazer animações (por exemplo, alguns mapas 2D de contorno / pcolormesh), é melhor limpar a figura e desenhar novos campos, em vez de fechar antigos e criar novos painéis de figuras. A velocidade será completamente diferente.
msi_gerva