T.Wong
T.Wong

Reputation: 21

animating image stack with vispy

I'm trying to migrate from MATLAB to Python and one of the things I frequently rely on during development in Matlab is the ability to rapidly visualize slices of a datacube by looping through layers and calling drawnow, e.g.

tst = randn(1000,1000,100);
for n = 1:size(tst, 3)
    imagesc(tst(:,:,n));
    drawnow;
end

When I tic/toc this in MATLAB it shows that the figure is updating at about 28fps. In contrast, when I try to do this using matplotlib's imshow() command this runs at a snails pace in comparison, even using set_data().

    import matplotlib as mp
    import matplotlib.pyplot as plt
    import numpy as np

    tmp = np.random.random((1000,1000,100))

    myfig = plt.imshow(tmp[:,:,i], aspect='auto')
    for i in np.arange(0,tmp.shape[2]):

        myfig.set_data(tmp[:,:,i])
        mp.pyplot.title(str(i))
        mp.pyplot.pause(0.001)

On my computer this runs at about 16fps with the default (very small) scale, and if I resize it to be larger and the same size as the matlab figure it slows down to about 5 fps. From some older threads I saw a suggestion to use glumpy and I installed this along with all of the appropriate packages and libraries (glfw, etc.), and the package itself works fine but it no longer supports the easy image visualization that was suggested in a previous thread.

I then downloaded vispy, and I can make an image with it using code from this thread as a template:

    import sys
    from vispy import scene
    from vispy import app
    import numpy as np

    canvas = scene.SceneCanvas(keys='interactive')
    canvas.size = 800, 600
    canvas.show()

    # Set up a viewbox to display the image with interactive pan/zoom
    view = canvas.central_widget.add_view()

    # Create the image
    img_data = np.random.random((800,800, 3))
    image = scene.visuals.Image(img_data, parent=view.scene)
    view.camera.set_range()

    # unsuccessfully tacked on the end to see if I can modify the figure.
    # Does nothing.
    img_data_new = np.zeros((800,800, 3))
    image = scene.visuals.Image(img_data_new, parent=view.scene)
    view.camera.set_range()

Vispy seems very fast and this looks like it will get me there, but how do you update the canvas with new data? Thank you,

Upvotes: 2

Views: 1026

Answers (1)

Etienne Cmb
Etienne Cmb

Reputation: 131

See ImageVisual.set_data method

# Create the image
img_data = np.random.random((800,800, 3))
image = scene.visuals.Image(img_data, parent=view.scene)
view.camera.set_range()

# Generate new data :
img_data_new = np.zeros((800,800, 3))
img_data_new[400:, 400:, 0] = 1.  # red square
image.set_data(img_data_new)

Upvotes: 1

Related Questions