This is one of the 100 recipes of the IPython Cookbook, the definitive guide to high-performance scientific computing and data science in Python.

6.6. Getting started with Vispy for high-performance interactive data visualizations

Vispy depends on NumPy and PyOpenGL. A backend library is necessary (PyQt4 or PySide for example).

This recipe has been tested with the development version of Vispy. You should clone the GitHub repository and install Vispy with python setup.py install.

The API used in this recipe might change in future versions.

  1. Let's import NumPy, vispy.app (to display a canvas) and vispy.gloo (object-oriented interface to OpenGL).
In [1]:
import numpy as np
from vispy import app
from vispy import gloo
  1. In order to display a window, we need to create a Canvas.
In [2]:
c = app.Canvas(keys='interactive')
  1. When using vispy.gloo, we need to write shaders. These programs written in a C-like language run on the GPU and give us full flexibility for our visualizations. Here, we create a trivial vertex shader that directly displays 2D data points (stored in the a_position variable) in the canvas. We give more details in There's more.
In [3]:
vertex = """
attribute vec2 a_position;
void main (void)
{
    gl_Position = vec4(a_position, 0.0, 1.0);
}
"""
  1. The other shader we need to create is the fragment shader. It lets us control the pixels' color. Here, we display all data points in black.
In [4]:
fragment = """
void main()
{
    gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
"""
  1. Next, we create an OpenGL Program. This object contains shaders and links the shader variables to NumPy data.
In [5]:
program = gloo.Program(vertex, fragment)
  1. We link the variable a_position to a (1000, 2) NumPy array containing the coordinates of 1000 data points. In the default coordinate system, the coordinates of the four canvas corners are (+/-1, +/-1).
In [8]:
program['a_position'] = np.c_[
        np.linspace(-1.0, +1.0, 1000).astype(np.float32),
        np.random.uniform(-0.5, +0.5, 1000).astype(np.float32)]
  1. We create a callback function for when the window is being resized. Updating the OpenGL viewport lets us ensure that Vispy uses the entire canvas.
In [9]:
@c.connect
def on_resize(event):
    gloo.set_viewport(0, 0, *event.size)
  1. We create a callback function when the canvas needs to be refreshed. This on_draw function renders the entire scene. First, we clear the window in white (it is necessary to do that at every frame). Then, we draw a succession of line segments using our OpenGL program.
In [10]:
@c.connect
def on_draw(event):
    gloo.clear((1,1,1,1))
    program.draw('line_strip')
  1. Finally, we show the canvas and we run the application.
In [11]:
c.show()
app.run();

You'll find all the explanations, figures, references, and much more in the book (to be released later this summer).

IPython Cookbook, by Cyrille Rossant, Packt Publishing, 2014 (500 pages).