将NumPy数组显示为使用Glumpy不断更新的图像 [英] Display NumPy array as continuously updating image with Glumpy
问题描述
我有一个使用NumPy和SciPy在Python中运行的仿真模型,它会在每次迭代中生成一个2D NumPy数组作为输出.我一直在使用matplotlib和imshow函数将此输出显示为图像.但是,我发现了有关Glumpy的信息,并且在其文档页面上显示:
借助IPython shell,可以在交互模式下运行脾气暴躁,当内容更改时,您可以在显示的数组中体验实时更新.
但是,我似乎无法通过他们给出的示例来弄清楚如何做到这一点.基本上,我的模型是作为一个函数运行的,其中有一个for循环以循环我正在运行的迭代次数.在for循环的每次迭代结束时,我要显示该数组.目前,我正在使用matplotlib将图像保存到png文件中,因为通过matplotlib在屏幕上显示图像似乎冻结了python进程.
我确定可以使用Glumpy做到这一点,我只是不确定如何做到,而且我找不到任何有用的教程.
完全不存在笨拙的文档!这是一个简单模拟的示例,将具有glumpy
的数组可视化与matplotlib
进行了比较:
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()
使用matplotlib
和GTKAgg
作为后端,并使用blit
避免每次绘制背景,我可以达到约95 FPS.使用Glumpy
时,即使我目前在笔记本电脑上的图形设置相当差劲,我仍然可以获得大约250-300 FPS.话虽这么说,Glumpy
才是工作的好去处,除非您要处理大型矩阵,或者出于任何原因需要很高的帧率,否则我会坚持将matplotlib
与blit
配合使用. /p>
I've got a simulation model running in Python using NumPy and SciPy and it produces a 2D NumPy array as the output each iteration. I've been displaying this output as an image using matplotlib and the imshow function. However, I've found out about Glumpy, and on its documentation page it says:
Thanks to the IPython shell, glumpy can be ran in interactive mode where you can experience live update in displayed arrays when their contents is changed.
However, I can't seem to work out how to do this with the examples they've given. Basically my model runs as a single function which has a big for loop in it to loop for the number of iterations I'm running. At the end of each iteration of the for loop I want to display the array. At the moment I'm using matplotlib to save the image out to a png file, as displaying it on the screen through matplotlib seems to freeze the python process.
I'm sure there's a way to do this with Glumpy, I'm just not sure how, and I can't find any useful tutorials.
The Glumpy documentation is fairly nonexistent! Here's an example of a simple simulation, comparing array visualisation with glumpy
against matplotlib
:
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()
Using matplotlib
with GTKAgg
as my backend and using blit
to avoid drawing the background each time, I can hit about 95 FPS. With Glumpy
I get about 250-300 FPS, even though I currently a fairly crappy graphics setup on my laptop. Having said that, Glumpy
is a bit more fiddly to get working, and unless you are dealing with huge matrices, or you need a very high framerate for whatever reason, I would stick with using matplotlib
with blit
.
这篇关于将NumPy数组显示为使用Glumpy不断更新的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!