将NumPy数组显示为使用Glumpy不断更新的图像 [英] Display NumPy array as continuously updating image with Glumpy

查看:192
本文介绍了将NumPy数组显示为使用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()

使用matplotlibGTKAgg作为后端,并使用blit避免每次绘制背景,我可以达到约95 FPS.使用Glumpy时,即使我目前在笔记本电脑上的图形设置相当差劲,我仍然可以获得大约250-300 FPS.话虽这么说,Glumpy才是工作的好去处,除非您要处理大型矩阵,或者出于任何原因需要很高的帧率,否则我会坚持将matplotlibblit配合使用. /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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆