2011-04-15 42 views
1

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

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

两个数组,分配在内存中。不过,我将不得不绘制文件,其中包含几个千兆字节的信息迟早。

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

但是我仍然需要一个完整的绘图。所以只是一个迭代器,并逐行传递值不能完成我想。

+0

如果我们确定无法避免将两个巨大的数组传递给plot(),那么通过将N和N中的X值和Y值聚类(例如计算它们的平均值)来进行一些数组“压缩” )。所以这产生600000/N值。 – hymloth 2011-04-15 09:58:28

回答

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

0

你确实有必要绘制各个点?看起来密度图也可以工作,有这么多的数据点可用。你可以看看pylab的hexbin或numpy.histogram2d。对于这样的大文件,你可能不得不使用numpy.memmap,或者@samplebias说批量工作。