python 如何完全清除所有matplotlib图的内存

tuwxkamq  于 2023-03-28  发布在  Python
关注(0)|答案(6)|浏览(194)

我有一个数据分析模块,其中包含多次调用matplotlib.pyplot API的函数,每次运行时生成多达30个数字。这些数字在生成后立即写入磁盘,因此我需要从内存中清除它们。
目前,在我的每个函数结束时,我做:

import matplotlib.pyplot as plt

plt.clf()

然而,我不太确定这条语句是否真的可以清空内存,我特别担心的是,每次我运行模块进行调试时,我的空闲内存空间都在不断减少。
每次将情节写入磁盘后,我需要做什么才能真正清除内存?

pxq42qpu

pxq42qpu1#

特别是当您运行多个进程或线程时,最好定义您的figure变量并直接使用它:

from matplotlib import pyplot as plt

f = plt.figure()
f.clear()
plt.close(f)

在任何情况下,都必须合并使用plt.clear()和plt.close()

更新(2021/01/21)

如果您使用的是MacOS系统沿着默认后端(称为“MacOSX”),这不起作用(至少在大苏尔)。我找到的唯一解决方案是切换到其他知名的后端,如TkAgg,Cairo等。要做到这一点,只需输入:

import matplotlib
matplotlib.use('TkAgg') # Your favorite interactive or non-interactive backend
yhxst69z

yhxst69z2#

经过一个星期的试验,我得到了我的解决方案!希望它可以帮助你。我的演示附件。

import matplotlib.pyplot as plt
import numpy as np

A = np.arange(1,5)
B = A**2

cnt=0
while(1):  
    cnt = cnt+1
    print("########### test %d ###########" % cnt)

    # here is the trick: 
    # set the figure a 'num' to prevent from re-malloc of a figure in the next loop 
    # and set "clear=True" to make the figure clear
    # I never use plt.close() to kill the figure, because I found it doesn't work.
    # Only one figure is allocated, which can be self-released when the program quits.
    # Before: 6000 times calling of plt.figure() ~ about 1.6GB of memory leak
    # Now: the memory keeps in a stable level
    fig = plt.figure(num=1, clear=True)
    ax = fig.add_subplot()

    # alternatively use an other function in one line
    # fig, ax = plt.subplots(num=1,clear=True)

    ax.plot(A,B)
    ax.plot(B,A)

    # Here add the functions you need 
    # plt.show()
    fig.savefig('%d.png' % cnt)
jtw3ybtb

jtw3ybtb3#

我的数据分析模块包含调用Matplotlib pyplot API multiple的函数
你能编辑调用matplotlib的函数吗?我也遇到了同样的问题,我试着按照命令执行,但都不起作用。

plt.close(fig)
fig.clf()
gc.collect()
%reset_selective -f fig

然后一个技巧对我起作用了,而不是每次都创建一个新的图形,我将相同的fig对象传递给函数,这解决了我的问题。
例如使用,

fig = plt.figure()
for i in range(100):
    plt.plot(x,y)

作为替代,

for i in range(100):
    fig = plt.figure()
    plt.plot(x,y)
rkkpypqq

rkkpypqq4#

这更像是一个测试套件,而不是问题的答案。在这里,我展示了截至2021年12月,没有提供的解决方案实际上清除了内存。
我们需要以下库:

import os
import psutil 
import numpy
import matplotlib
import matplotlib.pyplot

我创建了一个函数来清除所有matplotlib内存:

def MatplotlibClearMemory():
    #usedbackend = matplotlib.get_backend()
    #matplotlib.use('Cairo')
    allfignums = matplotlib.pyplot.get_fignums()
    for i in allfignums:
        fig = matplotlib.pyplot.figure(i)
        fig.clear()
        matplotlib.pyplot.close( fig )
    #matplotlib.use(usedbackend)

我创建了一个脚本,创建了100个图形,然后尝试从内存中删除它们:

#Use TkAgg backend because it works better for some reason:
matplotlib.use('TkAgg')

#Create fake data for our figures:
x = numpy.arange(1000)

#Get system process information for printing memory usage:
process = psutil.Process(os.getpid())

#Check memory usage before we create figures:
print('BeforeFigures: ', process.memory_info().rss)  # in bytes

#Make 100 figures, and check memory usage:
for n in range(100):
    matplotlib.pyplot.figure()
    matplotlib.pyplot.plot(x, x)
print('AfterFigures:  ', process.memory_info().rss)  # in bytes

#Clear the all the figures and check memory usage:
MatplotlibClearMemory( )
print('AfterDeletion: ', process.memory_info().rss)  # in bytes

输出剩余内存:

>>> BeforeFigures: 76083200
>>> AfterFigures:  556888064
>>> AfterDeletion: 335499264

只有不到一半的内存被清空(如果使用标准后端的话会更少)。这个堆栈溢出页面的唯一有效解决方案是避免同时在内存中放置多个图形。

gblwokeq

gblwokeq5#

不幸的是,没有解决方案:
参见:https://github.com/matplotlib/matplotlib/issues/20300
这只会发生在你在GUI后台工作,创建新的图形,但不显示它们。这种使用方式是不合理的。所有相关场景都有工作使用模式。

oyt4ldly

oyt4ldly6#

答案很晚,但这对我很有效。我有一个很长的顺序代码生成许多图,它总是在过程结束时吃掉所有的RAM。而不是在每个图完成后调用fig.close(),我简单地重新定义了plt.figure函数,如下所示,以便自动完成:

import matplotlib.pyplot as plt
import copy
try:
   # if script it run multiple times, only redefine once
   plt.old_figure
except:
  # matplotlib is imported for the first time --> redefine
  plt.old_figure = copy.deepcopy(plt.figure)
  def newfig(*args):
    plt.show()
    plt.close("all")
  return plt.old_figure(*args)
  plt.figure = newfig

我很清楚这不是一个很好的解决方案,但是它简单,快速,并为我做的把戏!也许有一种方法来装饰plt.figure,而不是重新定义它。

相关问题