HOWTO · Matplotlib
Diferenças entre cla(), clf() e close() no Matplotlib
Saiba quando usar matplotlib.pyplot.cla() para limpar um objeto Axes, matplotlib.pyplot.clf() para limpar uma Figure inteira ou matplotlib.pyplot.close() para fechar uma Figure.
Nesta página
Escolha a função pelo objeto que você quer afetar: matplotlib.pyplot.cla() limpa os Axes atuais, matplotlib.pyplot.clf() limpa a Figure atual e matplotlib.pyplot.close() fecha uma Figure. São funções do pyplot, não métodos, e cada uma opera em um escopo diferente. Use cla() para redesenhar um único subplot, clf() para reutilizar uma Figure com um layout novo e close() quando você terminar com uma Figure.
A diferença em resumo
As três funções formam uma hierarquia de escopo. cla() atua na menor unidade, um único Axes. clf() atua na Figure inteira que contém esse Axes. close() vai um passo além e remove a Figure do pyplot por completo.
| Função | Atua sobre | Remove | O que sobrevive |
|---|---|---|---|
plt.cla() |
Os Axes atuais | Dados plotados, rótulos, título, legenda e outros conteúdos dos Axes | Os próprios Axes, sua posição no layout, todos os Axes vizinhos e a Figure |
plt.clf() |
A Figure atual | Todos os Axes da Figure e o conteúdo deles | O objeto Figure e sua janela, prontos para receber novos Axes |
plt.close() |
Uma Figure gerenciada pelo pyplot | O registro da Figure no pyplot (e sua janela em backends interativos) | Nada dessa Figure dentro do pyplot; as Figures vizinhas não são afetadas |
O escopo importa principalmente quando uma Figure contém vários subplots. Limpar um Axes o mantém no layout, de modo que sua posição e os outros subplots continuam disponíveis. Limpar uma Figure remove todos os seus Axes de uma vez, mas deixa a Figure disponível para novos Axes e gráficos. Fechar uma Figure encerra o gerenciamento que o pyplot faz dela, e é a única das três que libera os recursos da Figure.
As três funções do pyplot atuam sobre os Axes ou a Figure atuais, a menos que você selecione um destino antes. Se você já tem um objeto Axes ou Figure, as operações em nível de objeto ax.clear() e fig.clear() tornam o destino explícito, em vez de depender de quais Axes ou Figure estão atuais. Para close(), você pode passar a Figure diretamente, como em plt.close(fig).
matplotlib.pyplot.cla()
cla() limpa os dados plotados, os rótulos dos eixos, o título, a legenda e os demais conteúdos dos Axes atuais. Os próprios Axes permanecem na Figure, em sua posição original, de modo que uma grade de subplots mantém seu layout e cada subplot vizinho mantém seu gráfico. Limpar um Axes não o remove de fig.axes nem altera as posições de seus vizinhos.
Isso torna cla() a ferramenta certa para um loop de atualização: selecione os Axes, limpe seu conteúdo e plote os novos dados no mesmo lugar. É o padrão por trás de animações simples e de dashboards que atualizam um único painel enquanto o restante da Figure permanece intocado.
O exemplo a seguir constrói dois subplots e depois limpa apenas o segundo. As verificações impressas mostram que a Figure ainda contém os dois Axes, que o primeiro Axes ainda tem sua linha e que o segundo Axes não tem linhas e está com o título vazio.
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)
Saída:
axes=2; ax1_lines=1; ax2_lines=0; ax2_title=''
Antes da chamada, os dois subplots contêm uma curva:
Depois de plt.cla(), o segundo Axes está vazio, mas ainda ocupa seu lugar, e o primeiro subplot permanece inalterado:
Escolha cla() quando o arranjo dos subplots deve permanecer e apenas o conteúdo de um Axes deve ser atualizado. Se o seu código já tem a variável dos Axes, ax.clear() expressa a mesma intenção em nível de Axes sem mudar a seleção de Axes atuais do pyplot.
matplotlib.pyplot.clf()
matplotlib.pyplot.clf() limpa a Figure atual, incluindo todos os seus Axes e o conteúdo deles. Ela deixa o objeto Figure disponível para reutilização e não fecha o gerenciador de Figure associado, de modo que a mesma Figure — e, em uma sessão interativa, a mesma janela — pode ser preenchida novamente do zero. Não existe uma operação clf() por Axes, porque esta função trabalha no escopo da Figure.
Depois de clf(), a Figure não tem nenhum Axes, então você precisa criar novos Axes antes de plotar novamente; uma chamada simples a plt.plot() criará implicitamente um novo Axes para você. Se você tiver várias Figures abertas, selecione a pretendida antes de chamar plt.clf(); fig.clear() é o equivalente em nível de objeto e torna o destino explícito.
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)
Saída:
figure_axes=0; figure_open=True
A Figure começa contendo um gráfico de linhas e um gráfico de barras lado a lado:
A saída confirma que clf() removeu todos os Axes (figure_axes=0) enquanto a própria Figure permaneceu aberta (figure_open=True). Em seguida, o exemplo adiciona um novo Axes e desenha um único gráfico completamente diferente sobre a mesma Figure:
Use clf() quando quiser manter uma Figure disponível, mas reconstruir todos os seus gráficos ou seu layout de subplots do zero. Use cla() em vez disso quando outros Axes na mesma Figure precisam permanecer intocados.
matplotlib.pyplot.close()
matplotlib.pyplot.close() fecha uma Figure gerenciada pelo pyplot. Chamada sem argumentos, ela fecha a Figure atual. Passe um objeto Figure, seu número ou um nome de Figure registrado para mirar em uma Figure específica, por exemplo plt.close(fig), e passe 'all' para fechar todas as Figures de uma vez.
Fechar remove a Figure do registro do pyplot, de modo que plt.fignum_exists() não a reporta mais e o pyplot não mantém mais seu conteúdo na memória. Isso difere de limpar em um ponto importante: depois de close(), não resta nenhuma Figure no pyplot para reutilizar, enquanto depois de clf() a mesma Figure espera, vazia, por novo conteúdo. Em backends interativos, a janela da Figure também é destruída, embora o comportamento exato da janela visível dependa do backend e do contexto de execução.
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")
Saída:
open_before=[1, 2]
open_after=[2]; fig1_open=False
Depois da chamada, apenas a Figure 2 continua registrada, e é a Figure que permanece disponível para exibição ou salvamento:
Use close() sempre que criar Figures das quais você não precisa mais — acima de tudo em scripts e loops que geram muitas Figures. Se você precisa reutilizar a mesma Figure, limpe-a com clf() em vez disso; se apenas um subplot precisa ser atualizado, use cla() ou ax.clear().
Memória e ciclo de vida de uma Figure
As três funções também diferem no que custam. cla() e clf() são operações baratas e repetíveis: a Figure permanece registrada no pyplot, sua janela e seus buffers permanecem vivos e apenas o conteúdo é descartado. É exatamente o que você quer para uma Figure que será desenhada novamente. close() é a única que libera a própria Figure, e por isso é o único encerramento correto para uma Figure que não será desenhada novamente.
O pyplot mantém cada Figure criada registrada até que ela seja explicitamente fechada, e avisa quando esse registro fica grande demais. Criar Figures em um loop sem fechá-las acumula memória e acaba disparando um 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()}")
Saída:
figures_open=25
too_many_figures_warning=True
after_close_all=[]
Nem cla() nem clf() ajudariam nesse loop, porque o problema é o número de Figures registradas, não o conteúdo delas. A regra prática é: limpe quando a mesma Figure continua, feche quando ela não continua. Trabalhos em lote que salvam um arquivo por Figure devem chamar plt.close(fig) imediatamente após salvar, para que o pico de memória permaneça constante, não importa quantos relatórios o trabalho produza.
Qual função você deve usar?
- Redesenhar um painel de uma Figure com vários painéis, como em uma animação ou um dashboard ao vivo: use
cla()(ouax.clear()), para que o layout e os outros painéis sobrevivam. - Recomeçar uma Figure com um layout diferente mantendo a mesma janela ou o mesmo objeto Figure: use
clf()(oufig.clear()) e depois adicione Axes novos. - Terminou com uma Figure, especialmente dentro de um loop ou script em lote: use
close(), passando a Figure, seu número ou'all', para que o pyplot a libere.
Os erros mais comuns são usar clf() onde o pretendido era cla() — o que apaga silenciosamente todos os subplots da Figure, não apenas o atual —, chamar cla() enquanto os Axes atuais são os errados e esperar que uma Figure fechada ainda seja alcançável pelo pyplot depois. Em resumo: limpe um Axes com cla(), limpe todos os Axes de uma Figure com clf() e termine com uma Figure usando close().