Когда использовать cla (), clf () или close () для очистки графика в matplotlib?

542

Matplotlib предлагает там функции:

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

Документация не дает большого понимания того, в чем разница между этими функциями. Когда я должен использовать каждую функцию и что именно она делает?

southoz
источник

Ответы:

714

Все они делают разные вещи, так как matplotlib использует иерархический порядок, в котором окно рисунка содержит фигуру, которая может состоять из множества осей. Кроме того, есть функции из интерфейса pyplot и есть методы для Figureкласса. Я буду обсуждать оба случая ниже.

интерфейс pyplot

pyplotэто модуль, который собирает несколько функций, которые позволяют функционально использовать matplotlib. Я здесь предполагаю, что pyplotбыл импортирован как import matplotlib.pyplot as plt. В этом случае есть три разные команды, которые удаляют вещи:

plt.cla()очищает оси , то есть текущие активные оси на текущем рисунке. Это оставляет другие оси нетронутыми.

plt.clf()очищает всю текущую фигуру со всеми ее осями, но оставляет окно открытым, чтобы его можно было использовать для других графиков.

plt.close()закрывает окно , которое будет текущим, если не указано иное.

То, какие функции подходят вам лучше всего, зависит, таким образом, от вашего варианта использования.

Кроме close()того, функция позволяет указать, какое окно должно быть закрыто. Аргумент может быть либо номером, либо именем, заданным окну, когда оно было создано с помощью, figure(number_or_name)или это может быть figполученный экземпляр фигуры , то есть с помощью fig = figure(). Если аргумент не указан close(), текущее активное окно будет закрыто. Кроме того, есть синтаксис close('all'), который закрывает все цифры.

методы класса Figure

Кроме того, Figureкласс предоставляет методы для очистки фигур. Я предполагаю в следующем, что figэто экземпляр Figure:

fig.clf()очищает всю фигуру . Этот вызов эквивалентен plt.clf()только если figэто текущая цифра.

fig.clear() это синоним fig.clf()

Обратите внимание, что даже del figне закроет связанное окно рисунка. Насколько я знаю, единственный способ закрыть окно рисунка - это использовать plt.close(fig)как описано выше.

Дэвид Цвикер
источник
38
Поскольку close()это неспецифическая команда, я искал способ указать закрытие фигуры ( fig.close()это не функция). Правильный синтаксис: plt.close(fig).
Tyleha
что clear(), я не видел большой разницы cla()только с тем, что в осях паразитов только cla()лечится специально.
дашесы
1
В clear()моей функции нет matplotlib.pyplot(Версия 1.4.2 на MacOS). Не могли бы вы направить меня к соответствующей документации?
Дэвид Цвикер
2
И класс Figure, и класс Axes имеют clear()метод. Figure.clearЭквивалент clfи Axes.clearэквивалентен cla.
SiggyF
2
Это работает по отношению к Jupyter? Я продолжаю сталкиваться с ошибками памяти, потому что цифры не собираются мусором, когда я перезапускаю ячейку в jupyter.
CMCDragonkai
79

Есть только одна оговорка, которую я обнаружил сегодня. Если у вас есть функция, вызывающая график много раз, лучше использовать ее, plt.close(fig)а не fig.clf()каким-либо образом, первая не накапливается в памяти. Короче говоря, если речь идет о памяти, используйте plt.close (рис.) (Хотя кажется, что есть более эффективные способы, перейдите к концу этого комментария для соответствующих ссылок).

Таким образом, следующий скрипт создаст пустой список:

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

Принимая во внимание, что этот произведет список с пятью числами на этом.

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

Из документации выше мне не ясно, в чем разница между закрытием фигуры и закрытием окна. Может быть, это прояснит.

Если вы хотите попробовать полный сценарий, у вас есть:

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

Если память вызывает беспокойство, кто-то уже опубликовал обходной путь в SO, см. Создание фигуры с подсчетом ссылок.

Рамон Мартинес
источник
26
Спасибо за полезную перекрестную ссылку на вопрос подсчета ссылок. Именно так Matplotlib уже должен работать. Страшно и страшно, что цифры никогда не собираются мусором в соответствии со стандартным pyplotAPI.
Сесил Карри
1
Тем не менее, я обнаружил, что если нужно создавать анимации (например, некоторые 2D-карты контуров / pcolormesh), то лучше очистить фигуру и нарисовать новые поля вместо того, чтобы закрывать старые и создавать новые панели рисунков. Скорость будет совершенно другой.
msi_gerva