大PyPlot - 避免内存分配

时间:2011-04-15 08:00:59

标签: python memory-management file-io plot

我正在做一个相当大的PyPlot(Python matplotlib)(600000个值,每个32位)。实际上我想我可以简单地做这样的事情:

import matplotlib.pyplot as plt
plt.plot([1,2,3,4], [1,4,9,16], 'ro')
plt.axis([0, 6, 0, 20])

两个数组,都在内存中分配。但是我必须绘制文件,这些文件迟早会包含几千兆字节的信息。

如何避免将两个数组传递到plt.plot()

但是我还需要一个完整的情节。因此,我想,只是一个迭代器并且逐行传递值。

2 个答案:

答案 0 :(得分:3)

如果您正在谈论千兆字节的数据,您可以考虑批量加载和绘制数据点,然后将每个渲染图的图像数据分层到前一个。这是一个快速示例,内联注释:

import Image
import matplotlib.pyplot as plt
import numpy

N = 20
size = 4
x_data = y_data = range(N)

fig = plt.figure()

prev = None
for n in range(0, N, size):
    # clear figure
    plt.clf()

    # set axes background transparent for plots n > 0
    if n:
        fig.patch.set_alpha(0.0)
        axes = plt.axes()
        axes.patch.set_alpha(0.0)

    plt.axis([0, N, 0, N])

    # here you'd read the next x/y values from disk into memory and plot
    # them.  simulated by grabbing batches from the arrays.
    x = x_data[n:n+size]
    y = y_data[n:n+size]
    ax = plt.plot(x, y, 'ro')
    del x, y

    # render the points
    plt.draw()

    # now composite the current image over the previous image
    w, h = fig.canvas.get_width_height()
    buf = numpy.fromstring(fig.canvas.tostring_argb(), dtype=numpy.uint8)
    buf.shape = (w, h, 4)
    # roll alpha channel to create RGBA
    buf = numpy.roll(buf, 3, axis=2)
    w, h, _ = buf.shape
    img = Image.fromstring("RGBA", (w, h), buf.tostring())
    if prev:
        # overlay current plot on previous one
        prev.paste(img)
        del prev
    prev = img

# save the final image
prev.save('plot.png')

输出:

enter image description here

答案 1 :(得分:0)

你真的需要绘制个别积分吗?似乎密度图也可以正常工作,有这么多的数据点可用。您可以查看pylab的hexbin或numpy.histogram2d。对于这样的大文件,你可能不得不使用numpy.memmap,或者像@samplebias那样批量工作。