Matplotlib中的内存泄漏与PDFPages一起保存fig

2024-05-17 17:11:48 发布

您现在位置:Python中文网/ 问答频道 /正文

编辑:更新

我使用objgraph为内存泄漏中出现的'Reference'项打印出{a1}。似乎PdfPages保存了所有的图像,因为我遍历了它们并将它们保存到每个页面(所以可能只是PdfPages模块固有的东西)。我想我要修改我的代码,在每次迭代中编写一个小的PDF文件,然后使用pypdf将这些文件合并到我想要的更大的PDF文件中。在

编辑:我使用matplotlib1.3.1运行python2.7.3。我已经尝试打印出gc.garbage,但这返回一个空列表,因此似乎没有任何无法接收的对象。我也尝试过同时使用PDF和Agg后端,但这两个后端中仍然存在内存泄漏。我尝试具体地关闭轴(ax1cbaxes1),并在所有变量上显式地使用del(其效果是关闭后删除+3列表,但在保存到+5列表后增加+2列表)。在

我试图通过pcolormesh创建多个热图,并将它们保存到PDF中的一个页面中,然后重复这个过程,在PDF文件中创建多个带有数字的页面(为了这个例子,我将它降到每页只有一个图形)。在

savefig函数似乎发生了内存泄漏,起初看起来很小,但实际上是因为我希望能够保存非常大的PDF文件。在

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
from matplotlib import gridspec
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
import numpy as np

import resource
import gc
import objgraph

def plotfunction(i,pdf):

    fig = plt.figure()
    fig.set_figheight(25)
    fig.set_figwidth(64)

    gs = gridspec.GridSpec(1,2)
    ax1 = plt.subplot(gs[0],rasterized=True)

    heatmap1 = ax1.pcolormesh(np.random.uniform(size=(10,10)))

    cbaxes1 = plt.subplot(gs[1],rasterized=True)

    cb1 = plt.colorbar(heatmap1, cax= cbaxes1, use_gridspec = True)

    gc.collect()

    print 'Memory Growth before savefig  {round}: %s ({mb} MB)' .format(round=i,mb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024/1024) % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
    objgraph.show_growth()

    pdf.savefig(fig) # the memory leak seems to occur here

    gc.collect()

    print 'Memory Growth after savefig  {round}: %s ({mb} MB)' .format(round=i,mb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024/1024) % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
    objgraph.show_growth()

    fig.clf()
    plt.close(fig)
    plt.close('all')
    gc.collect()

    print 'Memory Growth after closing  {round}: %s ({mb} MB)' .format(round=i,mb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024/1024) % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
    objgraph.show_growth()


def main():

    pdf = PdfPages('output.pdf')
    for i in range(15):
        plotfunction(i,pdf)
        print 'Memory Growth outside function {round}: %s ({mb} MB)' .format(round=i,mb=resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024/1024) % resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
        gc.collect()
        objgraph.show_growth()
    pdf.close()

if __name__ == "__main__":

    main()

以下是显示内存泄漏的输出:

^{pr2}$

我尝试过使用多处理,避免pyplot,并像其他帖子中建议的那样将save移到另一个函数中,但是这些解决方案都没有解决内存泄漏问题。在

谢谢。在


Tags: objgraphimportselfpdfmatplotlibrupltmb