Skip to main content
`Ctrl`+`K`

Note

Go to the end to download the full example code.

# Update Image and Isocurve Visuals

Show use of SceneCanvas to display and update Image and Isocurve visuals using ViewBox visual.

    import sys
    import numpy as np
    from itertools import cycle

    from vispy import app, scene
    from vispy.scene import STTransform
    from vispy.util.filter import gaussian_filter
    from vispy.color import get_colormaps, get_color_names

    canvas = scene.SceneCanvas(keys='interactive',
                               title='Show update capabilities of Isocurve Visual',
                               show=True)
    canvas.show()

    # Setting up four viewboxes
    vb1 = scene.widgets.ViewBox(border_color='yellow', parent=canvas.scene)
    vb2 = scene.widgets.ViewBox(border_color='blue', parent=canvas.scene)
    vb3 = scene.widgets.ViewBox(border_color='red', parent=canvas.scene)
    vb4 = scene.widgets.ViewBox(border_color='purple', parent=canvas.scene)

    vb = (vb1, vb2, vb3, vb4)

    # add grid as central widget, add viewboxes into grid
    grid = canvas.central_widget.add_grid()
    grid.padding = 0
    grid.add_widget(vb1, 0, 0)
    grid.add_widget(vb2, 0, 1)
    grid.add_widget(vb3, 1, 0)
    grid.add_widget(vb4, 1, 1)

    # panzoom cameras for every viewbox
    for box in vb:
        box.camera = 'panzoom'
        box.camera.aspect = 1.0

    # Create random image
    img_data1 = np.empty((200, 100, 3), dtype=np.ubyte)
    noise = np.random.normal(size=(200, 100), loc=50, scale=150)
    noise = gaussian_filter(noise, (4, 4, 0)).astype(np.float32)
    img_data1[:] = noise[..., np.newaxis]

    # create 2d array with some function
    x, y = np.mgrid[0:2*np.pi:201j, 0:2*np.pi:101j]
    myfunc = np.cos(2*x[:-1, :-1]) + np.sin(2*y[:-1, :-1])
    myfunc = myfunc.astype(np.float32)

    # add image to viewbox1
    image1 = scene.visuals.Image(noise, parent=vb1.scene, cmap='cubehelix')
    # move image behind curves
    image1.transform = STTransform(translate=(0, 0, 0.5))
    vb1.camera.set_range()

    # add image to viewbox2
    image2 = scene.visuals.Image(myfunc, parent=vb2.scene, cmap='cubehelix')
    # move image behind curves
    image2.transform = STTransform(translate=(0, 0, 0.5))
    vb2.camera.set_range()

    # create some level for the isocurves
    levels1 = np.linspace(noise.min(), noise.max(), num=52, endpoint=True)[1:-1]
    levels2 = np.linspace(myfunc.min(), myfunc.max(), num=52, endpoint=True)[1:-1]

    # create curve 1a (image overlay, black) and 1b (plain, cubehelix colored)
    # to viewboxes 1 and 3
    curve1a = scene.visuals.Isocurve(
        noise, levels=levels1[::4], color_lev='k', parent=vb1.scene)
    curve1b = scene.visuals.Isocurve(
        noise, levels=levels1, color_lev='cubehelix', parent=vb3.scene)

    # create curve 2a (2darray overlay, black) and 2b (plain, cubehelix colored)
    # to viewboxes 2 and 4
    curve2a = scene.visuals.Isocurve(
        myfunc, levels=levels2[::4], color_lev='k', parent=vb2.scene)
    curve2b = scene.visuals.Isocurve(
        myfunc, levels=levels2, color_lev='cubehelix', parent=vb4.scene)

    # set viewport
    vb3.camera.set_range((-100, 200), (0, 200))
    vb4.camera.set_range((0, 100), (0, 200))

    # setup update parameters
    up = 1
    index = 1
    clip = np.linspace(myfunc.min(), myfunc.max(), num=51)
    cmap = cycle(get_colormaps())
    color = cycle(get_color_names())

    def update(ev):
        global myfunc, index, up, levels2, noise, cmap, color

        if index > 0 and index < 25:
            # update left panes rolling upwards
            noise = np.roll(noise, 1, axis=0)
            image1.set_data(noise)
            curve1a.set_data(noise)
            curve1b.set_data(noise)

            # update colors/colormap
            if (index % 5) == 0:
                curve1b.color = next(color)
                cm = next(cmap)
                image2.cmap = cm
                curve2b.color = cm

            # change isocurves by clipping data/or changing limits
            # update curve1b levels (clip)
            curve1b.levels = levels1[index:-index]

            # update curve2b data with clipped data
            im2 = np.clip(myfunc, clip[index], clip[-index])
            curve2b.set_data(im2)

            index += up
        else:
            # change index direction
            up = -up
            index += up

        canvas.update()

    # setup timer
    timer = app.Timer()
    timer.connect(update)
    # slow this down a bit to better see what happens
    timer.start(0)

    if __name__ == '__main__' and sys.flags.interactive == 0:
        app.run()

Total running time of the script: (0 minutes 36.329 seconds)

Gallery generated by Sphinx-Gallery