2010-10-15 53 views
8

我有一個模擬模型運行在Python中使用NumPy和SciPy,它會產生一個2D NumPy數組作爲輸出每次迭代。我一直使用matplotlib和imshow函數將此輸出顯示爲圖像。但是,我發現了Glumpy,並在其文檔頁面上提到:顯示NumPy數組作爲不斷更新圖像與Glumpy

感謝IPython shell,glumpy可以在交互模式下運行,您可以在顯示的數組中更改其內容時進行實時更新。

但是,我似乎無法解決如何用他們給出的例子來做到這一點。基本上我的模型是作爲一個單獨的函數運行的,它有一個很大的for循環來循環我正在運行的迭代次數。在for循環的每次迭代結束時,我想要顯示數組。目前我正在使用matplotlib將圖像保存到png文件中,因爲通過matplotlib在屏幕上顯示它似乎凍結了python進程。

我敢肯定有一種方法可以做到這一點與Glumpy,我只是不知道如何,我找不到任何有用的教程。

+0

你用matplotlib凍結腳本的問題相當普遍,通常只需要一個簡單的修復,比如使用* draw *而不是* plot *,或者在* -pylab *模式下運行ipython等。 – tom10 2010-10-16 22:37:52

+0

可以您發佈了用於顯示數組的代碼?另外,你的'matplotlib .__ version__'是什麼,因爲它們已經改變了最近在一些重要方面處理GUI循環的方式。 – wim 2011-07-21 13:24:52

回答

10

Glumpy文檔是不存在的!這裏有一個簡單的模擬的一個例子,與glumpymatplotlib比較陣列可視化:

import numpy as np 
import glumpy 
from OpenGL import GLUT as glut 
from time import time 
from matplotlib.pyplot import subplots,close 
from matplotlib import cm 

def randomwalk(dims=(256,256),n=3,sigma=10,alpha=0.95,seed=1): 
    """ A simple random walk with memory """ 
    M = np.zeros(dims,dtype=np.float32) 
    r,c = dims 
    gen = np.random.RandomState(seed) 
    pos = gen.rand(2,n)*((r,),(c,)) 
    old_delta = gen.randn(2,n)*sigma 
    while 1: 
     delta = (1.-alpha)*gen.randn(2,n)*sigma + alpha*old_delta 
     pos += delta 
     for ri,ci in pos.T: 
      if not (0. <= ri < r) : ri = abs(ri % r) 
      if not (0. <= ci < c) : ci = abs(ci % c) 
      M[ri,ci] += 1 
     old_delta = delta 
     yield M 

def mplrun(niter=1000): 
    """ Visualise the simulation using matplotlib, using blit for 
    improved speed""" 
    fig,ax = subplots(1,1) 
    rw = randomwalk() 
    im = ax.imshow(rw.next(),interpolation='nearest',cmap=cm.hot,animated=True) 
    fig.canvas.draw() 
    background = fig.canvas.copy_from_bbox(ax.bbox) # cache the background 

    tic = time() 
    for ii in xrange(niter): 
     im.set_data(rw.next())   # update the image data 
     fig.canvas.restore_region(background) # restore background 
     ax.draw_artist(im)   # redraw the image 
     fig.canvas.blit(ax.bbox)  # redraw the axes rectangle 

    close(fig) 
    print "Matplotlib average FPS: %.2f" %(niter/(time()-tic)) 

def gprun(niter=1000): 
    """ Visualise the same simulation using Glumpy """ 
    rw = randomwalk() 
    M = rw.next() 

    # create a glumpy figure 
    fig = glumpy.figure((512,512)) 

    # the Image.data attribute is a referenced copy of M - when M 
    # changes, the image data also gets updated 
    im = glumpy.image.Image(M,colormap=glumpy.colormap.Hot) 

    @fig.event 
    def on_draw(): 
     """ called in the simulation loop, and also when the 
     figure is resized """ 
     fig.clear() 
     im.update() 
     im.draw(x=0, y=0, z=0, width=fig.width, height=fig.height) 

    tic = time() 
    for ii in xrange(niter): 
     M = rw.next()   # update the array   
     glut.glutMainLoopEvent() # dispatch queued window events 
     on_draw()   # update the image in the back buffer 
     glut.glutSwapBuffers()  # swap the buffers so image is displayed 

    fig.window.hide() 
    print "Glumpy average FPS: %.2f" %(niter/(time()-tic)) 

if __name__ == "__main__": 
    mplrun() 
    gprun() 

使用matplotlibGTKAgg作爲我的後端和使用blit避免每次繪製背景,我可以打大約95 FPS。與Glumpy我得到大約250-300 FPS,即使我目前在我的筆記本電腦上相當蹩腳的圖形設置。話雖如此,Glumpy是一個更加繁瑣的工作,除非你正在處理巨大的矩陣,或者無論什麼原因你需要非常高的幀率,我堅持使用matplotlibblit

相關問題