Code Monkey home page Code Monkey logo

vispy's Introduction

VisPy: interactive scientific visualization in Python

Main website: http://vispy.org

Build Status Coverage Status Zenodo Link Contributor Covenant


VisPy is a high-performance interactive 2D/3D data visualization library. VisPy leverages the computational power of modern Graphics Processing Units (GPUs) through the OpenGL library to display very large datasets. Applications of VisPy include:

  • High-quality interactive scientific plots with millions of points.
  • Direct visualization of real-time data.
  • Fast interactive visualization of 3D models (meshes, volume rendering).
  • OpenGL visualization demos.
  • Scientific GUIs with fast, scalable visualization widgets (Qt or IPython notebook with WebGL).

Releases

See CHANGELOG.md.

Announcements

See the VisPy Website.

Using VisPy

VisPy is a young library under heavy development at this time. It targets two categories of users:

  1. Users knowing OpenGL, or willing to learn OpenGL, who want to create beautiful and fast interactive 2D/3D visualizations in Python as easily as possible.
  2. Scientists without any knowledge of OpenGL, who are seeking a high-level, high-performance plotting toolkit.

If you're in the first category, you can already start using VisPy. VisPy offers a Pythonic, NumPy-aware, user-friendly interface for OpenGL ES 2.0 called gloo. You can focus on writing your GLSL code instead of dealing with the complicated OpenGL API - VisPy takes care of that automatically for you.

If you're in the second category, we're starting to build experimental high-level plotting interfaces. Notably, VisPy now ships a very basic and experimental OpenGL backend for matplotlib.

Installation

Please follow the detailed installation instructions on the VisPy website.

Structure of VisPy

Currently, the main subpackages are:

  • app: integrates an event system and offers a unified interface on top of many window backends (Qt4, wx, glfw, jupyter notebook, and others). Relatively stable API.
  • gloo: a Pythonic, object-oriented interface to OpenGL. Relatively stable API.
  • scene: this is the system underlying our upcoming high level visualization interfaces. Under heavy development and still experimental, it contains several modules.
    • Visuals are graphical abstractions representing 2D shapes, 3D meshes, text, etc.
    • Transforms implement 2D/3D transformations implemented on both CPU and GPU.
    • Shaders implements a shader composition system for plumbing together snippets of GLSL code.
    • The scene graph tracks all objects within a transformation graph.
  • plot: high-level plotting interfaces.

The API of all public interfaces are subject to change in the future, although app and gloo are relatively stable at this point.

Code of Conduct

The VisPy community requires its members to abide by the Code of Conduct. In this CoC you will find the expectations of members, the penalties for violating these expectations, and how violations can be reported to the members of the community in charge of enforcing this Code of Conduct.

Governance

The VisPy project maintainers make decisions about the project based on a simple consensus model. This is described in more detail on the governance page of the vispy website as well as the list of maintainers.

In addition to decisions about the VisPy project, there is also a steering committee for the overall VisPy organization. More information about this committee can also be found on the steering committee page of the vispy website, along with the organization's charter and other related documents (linked in the charter).

Genesis

VisPy began when four developers with their own visualization libraries decided to team up: Luke Campagnola with PyQtGraph, Almar Klein with Visvis, Cyrille Rossant with Galry, Nicolas Rougier with Glumpy.

Now VisPy looks to build on the expertise of these developers and the broader open-source community to build a high-performance OpenGL library.


External links

vispy's People

Contributors

adamlwgriffiths avatar aganders3 avatar alexjc avatar allebacco avatar almarklein avatar asnt avatar astrofrog avatar bollu avatar brisvag avatar campagnola avatar czaki avatar dependabot[bot] avatar djhoese avatar etiennecmb avatar fschill avatar guillaumefavelier avatar hmaarrfk avatar inclement avatar kmuehlbauer avatar larsoner avatar mfkaptan avatar michaelaye avatar mssurajkaiga avatar nippoo avatar qulogic avatar rossant avatar rougier avatar sylm21 avatar thentech avatar tlambert03 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vispy's Issues

Refactor glapi

glapi.py is auto-generated. But it has happened a few times that people make changes to this file directly. We should split glapi.py in two parts, of which only one is auto-generated.

Perhaps we should glapi into a subpackage then.

While we're refactoring, we can perhaps also have a second look at where the vispy.gl namespace is generated (now in the root init.py).

program_input error

Get an error on oscilloscope.py (it used to work):

Traceback (most recent call last):
  File "oscilloscope.py", line 138, in on_paint
    visual.draw(transform)
  File "oscilloscope.py", line 79, in draw
    self.program.uniforms['color'] = self.color
  File "../vispy/oogl/program_inputs.py", line 43, in __setitem__
    self._set(k, v)
  File "../vispy/oogl/program_inputs.py", line 94, in _set
    self._apply(name, value)
  File "../vispy/oogl/program_inputs.py", line 198, in _apply
    _name, length, type = gl.glGetActiveUniform(self._program.handle, loc)
  File "/usr/locaL/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/OpenGL/latebind.py", line 61, in __call__
    return self.wrapperFunction( self.baseFunction, *args, **named )
  File "/usr/locaL/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/OpenGL/GL/VERSION/GL_2_0.py", line 213, in glGetActiveUniform
    raise IndexError( 'Index %s out of range 0 to %i' % (index, max_index - 1, ) )
IndexError: Index 4 out of range 0 to 1
Error invoking callback for event: <PaintEvent blocked=False handled=False native=None region=None source=<__main__.Canvas object at 0x107548210> sources=[<__main__.Canvas object at 0x107548210>] type=paint>
(0.1, 1.0, 0.1, 1.953125000000001e-11)```

Mechanism to deal with inconsistencies with OpenGL and ES 2.0

It would be nice if the code we wrote would be more ES 2.0-ish, and we would not need to enable point sprites for instance.

It should be pretty easy to analyze the shading code at link-time and determine any extra stuff that need to be enabled.

Further, we could automatically add the #version 120 on top of the shader code.

hello_fbo.py doesn't work on Retina MBP OS X 10.8

Error:

$ python hello_fbo.py 
Error compiling shader <FragmentShader 'textured fragment shader'>
    on line 8: '/' does not operate on 'float' and 'int'
        float scalefactor = 1.0 / (c_sze * c_sze * 4 + 1);
    on line 14: Use of undeclared identifier 'scalefactor'
        gl_FragColor.rgb += color * scalefactor;
Traceback (most recent call last):
  File "hello_fbo.py", line 117, in on_paint
    with self._program2 as prog:
  File "/Users/nippoo/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/vispy/oogl/__init__.py", line 87, in __enter__
    self._enable()
  File "/Users/nippoo/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/vispy/oogl/program.py", line 158, in _enable
    self._enable_shaders()
  File "/Users/nippoo/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/vispy/oogl/program.py", line 220, in _enable_shaders
    shader._enable()
  File "/Users/nippoo/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/vispy/oogl/shader.py", line 94, in _enable
    raise RuntimeError(errors)
RuntimeError: ERROR: 0:8: '/' does not operate on 'float' and 'int'
ERROR: 0:14: Use of undeclared identifier 'scalefactor'

game of life example does not work (ubuntu)

The behavior I get is rapid flashing between two frames; no modification is made to the textures. With a little digging I see that the FBO is not created correctly. There are several related problems here:

  • glGenRenderBuffers and glGenFramebuffers both point to <bound method GLES2._glFuncNotAvailable of <API for OpenGL ES 2.0>>
  • RenderBuffer. and FrameBuffer._create should have checked self._handle != None. Alternately, calling _glFuncNotAvailable should raise an exception rather than return None.
  • For both classes, _handle has the default value of 0, which might be considered a valid buffer name on some systems (the spec does not seem to be specific about what values constitute valid names). I suggest using a default value None

Amount of magic to specify uniforms and attributes

Summary

We discussed this approach (which I know think really sucks):

program['a_pos'] = my_array  # Creates a VBO
program['a_pos'] = ClientArray(my_array)  # Uses the array directly
# WTF!

Besides being confusing it allows a sloppy style of using oogl that can byte the user in the ass when he starts using updating attributes in this way.

I propose to not do any magic VertexBuffer creating and instead just document well that specifying an array as an attribute works, but is not very efficient.

What we discussed

During Euroscipy we discussed about creating a VertexBuffer automatically when the user does:
program['a_position'] = position_array

He could also do (to make it explicit):
program['a_position'] = VertexBuffer(position_array)

Similarly, we could allow: program['s_texture'] = image_array

Further there is a Program.set_var() function that can be used to set VertexBuffers that contain structured data (from a structured numpy array). It also allows setting attributes and uniforms as keyword arguments.

Finally, we discussed that to explicitly use a client-side array, the user should do something like:
program['a_position'] = ClientArray(position_array)

What I did

The above is l currently mostly implemented. When the user uses this syntax to update a texture or attribute, a warning is given, because he should use a VBO (and update that) or explicitly use a client side array.

What I did not (yet) do is the ClientArray syntax. Instead if a user uses Program.set_var() there is no auto-conversion.

My worries

I think it is bad practice to automatically convert a given numpy array to a VertexBufer (let alone a Texture), because it allows a style of programming that can become very inefficient if the user makes his code more complex and starts updating stuff. Sure, we warn the user, but this is not optimal.

Also, I think the ClientArray syntax really sucks:

program['a_position'] = my_array  # Creates a VBO
program['a_position'] = oogl.ClientArray(my_array)  # Uses the array directly
# WTF

The approach that I took now (Program.set_var() does not do magic) is also far from optimal, because it is confusing.

Proposal

I propose that we force the user to a way of working that is clear and efficient.

I propose that Program does not automatically create VertexBuffers or Textures.

There are two downsides:

  1. The user will have to type a tiny bit more.
  2. The unattentive user may forget to use oogl.VertexBuffer and use a client-side array.

I think (1) is worth it, since it just makes things more explicit and much less confusion. For (2) I would argue that this is an API to OpenGL, and users should know a bit about it when they use it. We document this behaviour well and place a warning in the documentation. Further, most examples will use an VBO anyway.

Experiment with data transformation

The design of the data transformation system is one of the main challenges of the library. We should come up with a flexible and powerful way of dealing with arbitrary complex transformations on the CPU and the GPU.

We need to think about that during the work on the visuals and the shader templating system.

A few issues:

  • Data normalization like "pixel transfer": scale and bias. Data should be normalized on the GPU around the origin with low values (typically abs < 1) so that we have good precision when zooming.
  • World wind jitter problem: loss of precision with 32-bit floating points at high values ==> need to normalize the data on the CPU (64 bit) before converting in 32 bit.
  • Look transformation tutorial on matplotlib.
  • Non-linear transformation: polar plot, geographical projections (like in Cartopy, etc.). We don't have to implement that ourselves, but the transformation API should be flexible enough to support them nicely.

The best way to design a good API is to write experiments (using OOGL) for very specific use cases:

  • One with the world wind jitter problem: very long signal between 0 and 1e6: when zooming at high values, x coordinates are completely messed up.
  • One with a polar plot.
  • A grid where the ticks show values in the data coordinate system but where data normalization happens.

Canvas geometry

There is currently no way to set a canvas size without setting position while the inverse is possible. Doesn't make sense to me.

I would prefer to split geometry and have a set_size/get_size set_position/get_position, but also a set_x, get_x, set_y, get_y, set_width, get_width, set_height, get_height

Write utility functions to measure the FPS

It should be easy to evaluate precisely the FPS of a visualization on any script (e.g. app.measure_fps() or something).

@rougier suggestion: "I use to draw as fast as I can using the idle function (glutIdle will call you function when it has nothing else to do) and compute fps over a 5 seconds delay, that's generally enough to get a (rough) felling about speed."

Unit tests

Update the existing tests to make them work with nose (no need to use the native unittest Python module).

We should also set up tests for the various sub-packages:

  • event system
  • GL commands: if a GL context can be acquired, draw some basic shapes and compare them with ground truth (using image processing algorithms)
  • OOGL: write basic tests for OOGL features, get the list of generate GL calls (with the arguments) and compare that with the ground truth. This is pure Python here, no need for any GL context.

Button when mouse moves

From examples/app-event.py, when one move the mouse with a button pressed down, the event report no button pressed (button = 0).

Canvas show=True doesn't work

Take the examples/atom.py and tries:

app.Canvas.init(self, show=True)

The window is immediately shown while my canvas initalization is not yet finished. Showing the canvas should be deferred until the app is ran.

Reorganize/clean-up examples

We could create sub-folders in examples:

  • app: just show basic examples with Canvas and the event system
  • gl: visualizations with pure GL, no OOGL
  • oogl: visualization examples with OOGL

We could also get rid/merge/clean up some of the existing examples: we have many of them right now, even though we're just at the beginning! I think it's better to have few examples that are various enough rather than plenty similar ones.

Minor improvements on the main page of the website

A couple of suggestions concerning the main page:

  • "Who are we?" section on the main page, with our names and links to our respective libraries (and a note saying these libraries will be eventually merged in Vispy)
  • Screenshots
  • Link to "Examples" in the menu
  • Links to @rougier's PDF on "Presentation at EuroSciPy"

Timer events do not expose a 'time_since_last_frame' attribute

The current implementation of the Timer class does not give any information about the time elapsed since the last frame rendered.

Such an attribute is needed for users who want to animate entities at a specific speed, independent to the actual frame rate.

Shader parsing for easier debugging

When an attribute or uniform is specified incorrectly, it is currently ignored silently since we assume that the variable was optimized out of the program. This makes it more difficult to track down errors.

If each shader has the ability to report a list of its own attributes and uniforms, this would allow us to distinguish between optimized and non-existent variables. This could be done automatically for most shaders, or manually in the cases (if any) where parsing is too difficult.

Make a v0.2.0 release

With Nicolas' new implementation, bug fixes, new examples, code reorganization, cleaner repo :)

We should to a tag and maybe use the new releases feature on Github?

examples/app-glut.py

I get this on OSX:

on_resize (300x300)
Traceback (most recent call last):
File "_ctypes/callbacks.c", line 314, in 'calling callback function'
File "/Users/rougier/Development/Public/vispy/vispy/app/backends/glut.py", line 208, in on_draw
raise Exception('this should not happen')
Exception: this should not happen

Buffer api

Some comment on Buffer/VertexBuffer api

  1. The current buffer API doesn't allow to set subdata starting at offset 0. We need a count argument stating how much data we want to update (in set_data).
  2. Also, we should be able to only upload some sub-data without ever having a full copy on the CPU side. This means we need a set_size/get_size to specify the actual GPU buffer size.
  3. I think we need only a single "pending_data" variables since updating the whole data will invalidates all previous pending operations (the whole data will be rewritten)
  4. In the current implementation, I suspect the order between data/sub_data is not enforced and this might be problematic.
  5. Which make me think that since we do not have any local copy of the data, how to tell the user that his data will be uploaded later ? This might be problematic if he manipulates the data in the meantime.

Move event.py in a sub-package

Right now event.py is at the top-level in the package. I would prefer to have it in a sub-package (app?). There's no much sense to put it where it is now in my opinion.

scroll wheel

On OSX:

scroll wheel event does not seem consistant across backend (got float value in qt, int values in pyglet, and nothing in glut (but this last one is expected)).

Also, mouse wheel event are generated from the trackpad on my macbook pro and cannot distinguish between horizontal or vertical events in the callback (get only a single value delta).

New shader code

Some comment on new shader code (Program class)

  1. enable_objects is pretty useless as it stands now since it is only used in draw_elements for the index buffer. We should activate/deactivate the index buffer when drawing and that's it.
  2. Overloaded methods need docstring, at least for us to understand quickly what the method is doing.
  3. assert isinstance(name, str) is pretty useless test since it is followed by an if/elis/else
  4. set_data seems a better name for set_var since a bunch of data can be set

Prevent spewing of errors when error occurs in each draw

I propose each GLObject gets a status flag so that an error is shown only once. The error will probably propagate in the sense that all other related objects will fail as well, but at least its limited to a handful.

Related (since now self._handle < 0 sometimes means an error occurred): self._handle should be -1 if uninitialized, not 0.

Uniforms should stay attached with the program

The current implementation assigns the uniforms on each draw. According to the docs, the uniforms stay associated with the program, even if another program is selected.

I thought I tested this at some point, but I then needed to assign them at each draw. Needs another look when we have refactored the ShaderProgram class.

Buggy program/shader

In the example atom:

Comment the two lines:

        self.program.attributes['a_position'] = a_position
        self.program.attributes['a_color'] = a_color

and particles are still moving (but color does not change).

It is one of the many bugs I encountered with shader/program/buffer so I would strongly advice we (I ?) merge the second proposed implementation or at least test the current one very thoroughly.

GLSL version

boids.py and hello_sprite.py requires the GLSL version such that glPointCoord is found.

Experiment with batch rendering

How to render efficiently a large number of independent primitives? The old way of doing it is to use glMultiDrawArrays... but this function is not available in ES. It probably means it's not the best way of doing it, so we need to find something else.

Here are possible methods, and we should experiment with them.

First case: drawing lots of line segments with GL_LINE.*

  • Multiple lines: GL_LINES + index buffer and we're fine: no copy during backing.
  • Multiple lines: GL_LINES + double the number of points (+ extra point at the end of every line?)
  • (Multiple lines: two GL_LINES calls without index buffer (+ extra point)?)
  • For GL_LINE_STRIP, maybe a "discard" in the fragment shader, with a varying variable specifying whether we are between two primitives (no integer). Or alpha between primitives. Precision bug on some architectures (Unix).

Second case: rich lines or triangles or polygons with GL_TRIANGLE.*

  • GL_TRIANGLE_STRIP: use degenerate triangles between primitives.
  • Thick lines (GL_TRIANGLES and index buffer), no problem.

examples/app-pyglet.py

On OSX, reported event.text is wrong (get scancode instead):

If I press key "4" on my keyboard (which is "'" or "4" depending on shift/capslock), I always get 4.

examples/app-qt.py

If I press "é" on my keyboard, I get:

Traceback (most recent call last):
File "/Users/rougier/Development/Public/vispy/vispy/app/backends/qt.py", line 234, in keyPressEvent
text = str(ev.text()),
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 0: ordinal not in range(128)

(most likely utf-8 problem)

Canvas / Window

Why is the Canvas class named Canvas while it is truly a window ?
I think we'll need the canvas class later to express a part of a window that can be drawn upon.

OOGL/GL namespaces

There are currently two low-level GL namespaces: gl and oogl. The first one contains raw OpenGL ES commands, the second one implements an object-oriented layer on top of OpenGL. Even though we definitely need both, I fear it might be confusing for new-comers that even the simplest examples need two different namespaces that do basically the same thing.

I think it would be worth writing extremely simple functions in oogl that implement the most basic things, e.g. something like oogl.clear(r, g, b, a), maybe oogl.draw_elements(...), etc. At the very least, we could just write dumb wrappers like:

def clear(*args):
    gl.glClearColor(*args)
    gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

It would simplify the simplest examples, making them cleaner and easier to understand. I can already see beginners asking: "But what is the difference between vispy.gl and vispy.oogl? Why do I need them both just to display a black screen?" and so on.

Another advantage is that it would make the code conventions more uniform, i.e. we use names_with_underscores in OOGL but camelCase in GL, which is not really nice and might confuse beginners.

One goal could be the following: the most simple things could be done with either vispy.gl and no oogl (raw OpenGL), or vispy.oogl and no pure GL.

on_mouse_move / glut backend

On OSX, I get:

2013-08-08 11:41:53.912 Python[2485:f07] GLUT Warning: glutCurrentModifiers: do not call outside core input callback.

Twinkling display bug on Win8 laptop with AMD 7650M

I have a display bug on a new Sony VAIO laptop with Windows 8 64 bits and an AMD Radeon HD 7650M GPU (tried with latest stable Catalyst driver and beta driver 13.200). In all examples, the window alternates between the background color and the scene (2-4 times per second). This bug does not occur on other graphics libraries (e.g. Galry).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.