vispy / vispy

Main repository for Vispy
http://vispy.org
Other
3.33k stars 618 forks source link

cannot update image visual from timer #1710

Open shlomok613 opened 5 years ago

shlomok613 commented 5 years ago

I am having trouble updating an image visual from the timer. I can update it from a for loop like this:

    HEIGHT=600
    WIDTH=800
    canvas = scene.SceneCanvas(title='waterfall image')
    canvas.size = WIDTH, HEIGHT
    canvas.show()
    # canvas.measure_fps()

    # Set up a viewbox to display the image with interactive pan/zoom
    view = canvas.central_widget.add_view()
    view.camera.set_range()
    x = np.linspace(0., 1., WIDTH)

    data = np.zeros((HEIGHT, WIDTH))
    cm = Colormap(['w', 'r', 'g', 'b'])
    image = scene.visuals.Image(data=data, parent=view.scene, cmap=cm)
    index = 0

    for i in range(HEIGHT):
        data [i] = x
        image.set_data(data)
        image.update()

    app.run()

But when I replace the for loop with a timer the display fails to update:

   def on_timer(event):
        global index,data,image
        data [index] = x
        index += 1
        image.set_data(data)
        image.update()

    timer = app.Timer(interval='auto',connect=on_timer)
    timer.start()

    app.run()

Can anybody help?

Shlomo

djhoese commented 5 years ago

I tried running your code and got similar results. It is important to point out that in the first case the Image array is being updated (all rows) before it is shown/run with app.run().

I even tried moving to a subclass of SceneCanvas to see if this performed as expected and it didn't. This makes me think we're missing something simple.

djhoese commented 5 years ago

Got it! Try setting clim=[0, 1] when creating your Image. By default this is set to 'auto' and overwrites itself on the first draw. Auto will take the min/max of the current data and in your example that is (0, 0). It won't update these limits when you do set_data. For best performance you should set a static limit or re-set the clim property to 'auto' every time you call set_data.