使用 Glumpy 将 NumPy 数组显示为持续更新的图像

发布于 2024-09-27 18:50:59 字数 486 浏览 1 评论 0原文

我有一个使用 NumPy 和 SciPy 在 Python 中运行的模拟模型,它会生成一个 2D NumPy 数组作为每次迭代的输出。我一直使用 matplotlib 和 imshow 函数将此输出显示为图像。然而,我发现了 Glumpy,并且在它的文档页面上写着:

感谢 IPython shell,glumpy 可以在交互模式下运行,在这种模式下,当显示的数组内容发生更改时,您可以在显示的数组中体验实时更新。< /em>

但是,我似乎无法通过他们给出的示例弄清楚如何做到这一点。基本上,我的模型作为单个函数运行,其中有一个大的 for 循环,用于循环我正在运行的迭代次数。在 for 循环的每次迭代结束时,我想显示该数组。目前,我正在使用 matplotlib 将图像保存到 png 文件,因为通过 matplotlib 将其显示在屏幕上似乎会冻结 python 进程。

我确信有一种方法可以用 Glumpy 来做到这一点,我只是不确定如何做,而且我找不到任何有用的教程。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

幻梦 2024-10-04 18:50:59

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 的工作起来有点麻烦,除非您正在处理巨大的矩阵,或者无论出于何种原因需要非常高的帧速率,否则我会坚持使用 matplotlib 与 blit

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.

荒芜了季节 2024-10-04 18:50:59

使用 pyformulas 0.2.8 您可以使用 pf.screen 创建非阻塞屏幕:

import pyformulas as pf
import numpy as np

canvas = np.floor(np.random.normal(scale=50, size=(480,640,3)) % 256).astype(np.uint8)
screen = pf.screen(canvas)

while screen.exists():
    canvas = np.floor(np.random.normal(scale=50, size=(480,640,3)) % 256).astype(np.uint8)
    screen.update(canvas)

#screen.close()

免责声明:我是 pyformulas 的维护者

Using pyformulas 0.2.8 you can use pf.screen to create a non-blocking screen:

import pyformulas as pf
import numpy as np

canvas = np.floor(np.random.normal(scale=50, size=(480,640,3)) % 256).astype(np.uint8)
screen = pf.screen(canvas)

while screen.exists():
    canvas = np.floor(np.random.normal(scale=50, size=(480,640,3)) % 256).astype(np.uint8)
    screen.update(canvas)

#screen.close()

Disclaimer: I am the maintainer for pyformulas

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文