Matplotlib 提供了以下函数:
cla() # Clear axis
clf() # Clear figure
close() # Close a figure window
我应该在什么时候使用每个函数,它们具体是做什么的?
Matplotlib 提供了以下函数:
cla() # Clear axis
clf() # Clear figure
close() # Close a figure window
我应该在什么时候使用每个函数,它们具体是做什么的?
它们都有不同的功能,因为matplotlib使用分层顺序,其中一个图形窗口包含一个由许多轴组成的图形。此外,有来自pyplot界面的函数和Figure
类上的方法。我将在下面讨论这两种情况。
pyplot
是一个收集了几个函数的模块,允许以函数方式使用matplotlib。我在这里假设已经导入pyplot
,并命名为import matplotlib.pyplot as plt
。
在这种情况下,有三个不同的命令可以移除东西:
请参见matplotlib.pyplot
函数:
plt.cla()
清除轴,即当前图像中的活动轴。 它不会影响其他轴。plt.clf()
清除整个当前带有所有轴的图形,但保留打开的窗口,以便可以重复使用它进行其他绘图。plt.close()
关闭窗口,如果没有特别指定,则为当前窗口。因此,哪个函数最适合您取决于您的用例。
close()
函数可以让你指定要关闭的窗口。该参数可以是数字或名称,这些数字或名称在创建图形使用figure(number_or_name)
时赋予窗口,也可以是图形实例fig
,例如使用fig = figure()
获得。如果没有给close()
提供参数,则将关闭当前活动窗口。此外,还有语法close('all')
,它会关闭所有图形。Figure
类提供了清除图形的方法。以下内容假设fig
是Figure
的一个实例:
fig.clf()
清除整个图形。如果fig
是当前图形,则此调用等效于plt.clf()
。
fig.clear()
是fig.clf()
的同义词。del fig
也不能关闭相关联的图形窗口。据我所知,唯一关闭图形窗口的方法是使用如上所述的plt.close(fig)
。今天我发现一个需要注意的问题。如果你有一个函数需要频繁调用plot方法,最好使用plt.close(fig)
而不是fig.clf()
,因为前者不会在内存中累积。简而言之,如果你关心内存,请使用plt.close(fig)(尽管似乎有更好的方法,请查看本评论末尾的相关链接)。
因此,以下代码将生成一个空列表:
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())
如果内存是一个问题,有人在stackoverflow上发布了一个解决方法,请参见: Create a figure that is reference counted
plt.cla()的意思是清除当前轴
plt.clf()的意思是清除当前图形
此外,还有plt.gca()(获取当前轴)和plt.gcf()(获取当前图形)
正如David Zwicker所解释的那样,这些方法清除的是不同的内容。本文将提供一些示例,以帮助澄清何时使用它们。
如果您想要重复使用图形的特定配置(如面颜色、dpi、布局等)用于另一个图形,请使用fig.clf()
清除图形上的当前对象(包括Axes)。请注意,这不会删除先前实例化的Figure实例,而只会清除其中的对象。因此,在下面的代码中,一个单独的Figure实例被重复使用以生成2个图像文件。fig.clf()
会删除Axes,所以重要的是在其上添加一个新的Axes以便绘制内容。ax.cla()
清除Axes上的当前对象(例如刻度、标题、绘图等)。特别是,图形上的Axes的位置是一个重要的属性,可以重复使用(例如,图形上的小Axes可以叠加在较大的Axes上)。plt.close()
。这在使用具有交互模式的IDE(如Jupyter或Spyder)且不想看到脚本创建的图形时特别有用。如果使用Python shell(附带Python安装的IDLE),则它会关闭显示图形的窗口。即使关闭了窗口,Figure实例仍然在内存中,并且包含在其上定义的任何对象。例如,在下面的代码中,即使关闭了fig
,仍然可以对其进行操作。但是,由于图形/Axes没有被清除,fig
中的内容仍然存在。Heberto Mayorquin 指出 plt.close()
可以节省内存。然而,下面的内存分配追踪显示,如果在循环中需要创建大量相似的图像,使用 clf()
或 cla()
清除实际上比关闭窗口并使用 plt.close()
创建新的图形实例更节省内存。
然而,有一个需要注意的地方,由于 cla()
/clf()
是用来重复使用先前定义的 Axes/Figure 的,所以在循环之外(创建图像文件的循环)定义要重复使用的 Figure 对象非常重要。我还在测试中包含了“错误”的使用方式(每次绘制新图形时都创建一个新的 Figure 实例),这确实比在循环中创建新的 Figure 并关闭它更加耗费资源。
close:
current memory usage is 12,456 KB; peak was 13,402 KB.
======================================================
cla:
current memory usage is 899 KB; peak was 1,451 KB.
======================================================
clf:
current memory usage is 3,806 KB; peak was 8,061 KB.
======================================================
clf_wrong:
current memory usage is 7,392 KB; peak was 10,494 KB.
======================================================
cla_wrong:
current memory usage is 29,174 KB; peak was 29,650 KB.
======================================================
import os
import tracemalloc
import matplotlib.pyplot as plt
def close(n):
for i in range(n):
fig = plt.figure(facecolor='white', figsize=(6,3), dpi=36)
ax = fig.add_subplot()
ax.plot([100, 0, i])
fig.savefig(f'{i}.png')
plt.close(fig)
def cla(n):
fig = plt.figure(facecolor='white', figsize=(6,3), dpi=36)
ax = fig.add_subplot()
for i in range(n):
ax.plot([100, 0, i])
fig.savefig(f'{i}.png')
ax.cla()
def clf(n):
fig = plt.figure(facecolor='white', figsize=(6,3), dpi=36)
for i in range(n):
ax = fig.add_subplot()
ax.plot([100, 0, i])
fig.savefig(f'{i}.png')
fig.clf()
def cla_wrong(n):
for i in range(n):
fig = plt.figure(facecolor='white', figsize=(6,3), dpi=36)
ax = fig.add_subplot()
ax.plot([100, 0, i])
fig.savefig(f'{i}.png')
ax.cla()
def clf_wrong(n):
for i in range(n):
fig = plt.figure(facecolor='white', figsize=(6,3), dpi=36)
ax = fig.add_subplot()
ax.plot([100, 0, i])
fig.savefig(f'{i}.png')
fig.clf()
if __name__ == '__main__':
for func in (close, cla, clf, clf_wrong, cla_wrong):
tracemalloc.start()
func(100)
size, peak = tracemalloc.get_traced_memory()
tracemalloc.stop()
# delete the saved image files
for f in os.listdir():
if f.endswith('.png'):
os.remove(f)
print(f"{func.__name__}:\ncurrent memory usage is {size/1024:,.0f} KB; \
peak was {peak/1024:,.0f} KB.")
print("======================================================")
pyplot
API时,图形从不被垃圾回收,这同样令人恐惧和骇人听闻。 - Cecil Curryplt.clf()
后跟plt.close()
,那么内存会被正确释放。仅仅使用plt.close()
仍然会导致每个打开的图形增加残留内存。 - DrBwts