2

我正在使用以下代码创建一组颜色编码的线图:

for j in idlist[i]:
    single_traj(lonarray, latarray, parray)

plt.savefig(savename, dpi = 400)
plt.close('all')
plt.clf()

在哪里:

def single_traj(lonarray, latarray, parray, linewidth = 0.7):
    """
    Plots XY Plot of one trajectory, with color as a function of p
    Helper Function for DrawXYTraj
    """
    global lc
    x = lonarray
    y = latarray
    p = parray

    points = np.array([x,y]).T.reshape(-1,1,2)
    segments = np.concatenate([points[:-1], points[1:]], axis=1)

    lc = col.LineCollection(segments, cmap=plt.get_cmap('Spectral'), 
                            norm=plt.Normalize(100, 1000), alpha = 0.8)
    lc.set_array(p)
    lc.set_linewidth(linewidth)
    plt.gca().add_collection(lc)

不知何故,这个循环使用了大量内存(> ~10GB),在保存绘图后仍在使用。我用 hpy 查看内存使用情况

Partition of a set of 27472988 objects. Total size = 10990671168 bytes.
Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
    0 8803917  32 9226505016  84 9226505016  84 dict of matplotlib.path.Path
    1 8888542  32 711083360   6 9937588376  90 numpy.ndarray
    2 8803917  32 563450688   5 10501039064  96 matplotlib.path.Path
    3     11   0 219679112   2 10720718176  98 guppy.sets.setsc.ImmNodeSet
    4  25407   0 77593848   1 10798312024  98 list
    5  89367   0 28232616   0 10826544640  99 dict (no owner)
    6   7642   0 25615984   0 10852160624  99 dict of matplotlib.collections.LineCollection
    7  15343   0 16079464   0 10868240088  99 dict of
                                            matplotlib.transforms.CompositeGenericTransform
    8  15327   0 16062696   0 10884302784  99 dict of matplotlib.transforms.Bbox
    9  53741   0 15047480   0 10899350264  99 dict of weakref.WeakValueDictionary

此时情节已经保存,因此所有与 matplotlib 相关的对象都应该消失了……但我无法“找到”这些对象,这意味着我不知道如何删除它们。

编辑:

这是一个重现泄漏的独立示例(savefig 由于某种原因引发错误,但无论如何都不相关):

# Memory leak test!

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.collections as col

def draw():

    x = range(1000)
    y = range(1000)
    p = range(1000)

    fig = plt.figure(figsize = (12,8))
    ax = plt.gca()   
    ax.set_aspect('equal')


    for i in range(1000):
        if i%100 == 0:
            print i
        points = np.array([x,y]).T.reshape(-1,1,2)
        segments = np.concatenate([points[:-1], points[1:]], axis=1)

        lc = col.LineCollection(segments, cmap=plt.get_cmap('Spectral'), 
                                norm=plt.Normalize(0, 1000), alpha = 0.8)
        lc.set_array(p)
        lc.set_linewidth(0.7)
        plt.gca().add_collection(lc)

    cb = fig.colorbar(lc, shrink = 0.7)
    cb.set_label('p')
    cb.ax.invert_yaxis()
    plt.tight_layout()

    #plt.savefig('./mem_test.png', dpi = 400)
    plt.close('all')
    plt.clf()


draw()

a = input('Wait...')

draw() 函数应该删除所有 plt 对象,但在调用函数后它们仍然会占用内存。我只是用 top/htop 检查它!

4

1 回答 1

2

从您的 hpy 转储看来,内存猪由大量matplotlib.path.Paths. 这可能是由于您的变量lc。你试过del lc吗?可能plt.close不是(至少不应该!)能够删除它们,因为它们在您的全局变量lc中。

于 2014-07-01T17:58:30.847 回答