2011-04-15 40 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說批量工作。