#!/usr/bin/env python # coding: utf-8 # > This is one of the 100 recipes of the [IPython Cookbook](http://ipython-books.github.io/), 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](https://github.com/vispy/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 # 2. In order to display a window, we need to create a **Canvas**. # In[2]: c = app.Canvas(keys='interactive') # 3. 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); } """ # 4. 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); } """ # 5. 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) # 6. 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)] # 7. 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) # 8. 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') # 9. 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](http://ipython-books.github.io/), by [Cyrille Rossant](http://cyrille.rossant.net), Packt Publishing, 2014 (500 pages).