1

Some context: I was looking into the vispy module to plot in realtime (or as close as possible to) data coming from an instrument. My attempt follow.

from vispy.plot import Fig
from vispy import app,scene
from vispy.visuals import TextVisual
import numpy as np
import Queue
FONT_SIZE = 14
MIN = 0
MAX = 1.1
w_size = 100
N = 5000
M = 2500
color_map = 'cubehelix'
q_size = 1000
Nb = 5

#generate (empty) initial data to fill the plot
data = np.zeros(N*M)
data = np.reshape(data, (N,M))

#setup the plot
fig = Fig(show = False,size = (16*w_size,9*w_size),bgcolor='black')
fig.title = 'my plot'
main_plot = fig[0,0].image(data = data,fg_color='w',cmap=color_map,clim=(MIN,MAX))
fig[0,0].view.camera.aspect = N/float(M) * 16./9.
title = scene.Label("someoutput", font_size=FONT_SIZE, color = 'w')
fig[0,0].grid.add_widget(title, row=0, col=4)
fig[0,0].grid[2,4].border_color = 'black'
fig[0,0].grid[2,4].bgcolor = 'black'
xlabel_title = scene.Label("x_axis [unit]", font_size=FONT_SIZE, color = 'w')
fig[0,0].grid.add_widget(xlabel_title, row=4, col=4)
ylabel_title = scene.Label("y_axis [unit]", font_size=FONT_SIZE,rotation=-90, color='w')
fig[0,0].grid.add_widget(ylabel_title, row=2, col=2)
scale = scene.ColorBarWidget(orientation='left',
             cmap=color_map,
             label='Some value',
             clim=(MIN,MAX),
             border_color = 'w',
             border_width = 1,
             label_color = 'w'
             )
fig[0,0].grid.add_widget(scale, row=2, col=6)
fig[0,0].cbar_right.width_max = \
    fig[0,0].cbar_right.width_min = 50

#fill a queue so to excude the generation time from the plotting time
q = Queue.Queue()
for i in range(q_size):
    new_data = (np.abs(0.5*np.random.randn(Nb*M)[:])).astype('float32')
    new_data = np.reshape(new_data, (Nb,M))
    q.put(new_data[:])

#update function
def update(ev):
    global main_plot, q, data, Nb,M,fig,index            


   #acquire
    new_data = q.get()

    #roll the plot data
    data[Nb:, :] = data[:-Nb, :]
    data[:Nb,:] = new_data

    #recycle the new data
    q.put(new_data)

    #update the plot
    main_plot.set_data(data)
    main_plot.update()



# setup timer
interv = 0.01
timer = app.Timer(interval = interv)
timer.connect(update)
timer.start(interval = interv)


if __name__ == '__main__':
    fig.show(run=True)
    app.run()

This code currently works but it's much slower than the data rate. In the vispy gallery, as well as in some examples, I saw much more points being plotted and updated. I think that the main problem is that I completely set each time all the data of the plot instead of shifting them and inserting new points.

I also had a look at this example: https://github.com/vispy/vispy/blob/master/examples/demo/scene/oscilloscope.py

However I don't know how to generalize the update function that rolls the data (I have no knowledge of OpenGL) and I cannot use the example as is because I need a quantitative color scale (that seems well implemented in vispy.plot).

The question: Is there a way to write a function that rolls the data of a plot generated with the vispy.plot class?

Thanks.

Oznerol
  • 73
  • 6

0 Answers0