Отображать массив NumPy как постоянно обновляемое изображение с помощью Glumpy - PullRequest
8 голосов
/ 15 октября 2010

У меня есть имитационная модель, работающая на Python с использованием NumPy и SciPy, и она выдает двумерный массив NumPy в качестве выходных данных на каждой итерации.Я отображал этот вывод как изображение, используя matplotlib и функцию imshow.Тем не менее, я узнал о Glumpy, и на его странице документации написано:

Благодаря оболочке IPython, Glumpy можно запустить в интерактивном режиме, где вы можете обновлять данные в отображаемых массивах,их содержание изменилось.

Однако я не могу понять, как это сделать с примерами, которые они привели.По сути, моя модель работает как отдельная функция, в которой есть большой цикл for для цикла, который я выполняю.В конце каждой итерации цикла for я хочу отобразить массив.В настоящее время я использую matplotlib для сохранения изображения в файл png, так как отображение его на экране через matplotlib, кажется, останавливает процесс python.

Я уверен, что есть способ сделать это сГлупый, я просто не уверен, как, и я не могу найти никаких полезных руководств.

Ответы [ 2 ]

10 голосов
/ 24 января 2013

Документация 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 кадров в секунду, хотя в настоящее время у меня довольно дурацкая графика на моем ноутбуке.Сказав это, Glumpy немного сложнее в работе, и если вы не имеете дело с огромными матрицами, или вам не нужна очень высокая частота кадров по какой-либо причине, я бы остановился на использовании matplotlib с blit.

1 голос
/ 01 апреля 2018

Используя 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

...