vispy's high-level interface is the experimental one, and its backend list still names Qt4
Main repository for Vispy
At a glance
- What is it?
- A BSD-3-Clause Python library that pushes interactive 2D and 3D visualisation onto the GPU through OpenGL, with four subpackages at three different stability levels. Two things are worth knowing before you rely on it. The interface aimed at people who do not know OpenGL is described in the same readme as experimental and under heavy development, while the low-level one is called relatively stable. And the window-backend list still names a toolkit generation that ended years ago, in a file committed to within the last week.
- Who is it for?
- vispy suits someone who already writes shader code, or who needs to visualise datasets far larger than a plotting library can hold, and for the second group the offscreen rendering and benchmark examples are the parts to read first. Four things to check first.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The interface non-OpenGL users need is the experimental one
The readme splits its audience into two and answers them separately, and the asymmetry is the most useful thing in the file.
The first group is people who know OpenGL or are willing to learn it, who want interactive visualisation in Python as easily as possible. The readme tells this group they can already start using the library, and points them at a Pythonic, array-aware, user-friendly interface to the mobile subset of the graphics API, whose purpose is stated plainly: so you can focus on writing your shader code instead of dealing with the complicated underlying API, which the library handles for you.
The second group is scientists with no OpenGL knowledge at all, looking for a high-level plotting toolkit. For them the readme says the project is starting to build those interfaces, and describes what exists as very basic and experimental.
So the audience with the largest need for a high-level abstraction is served by the least finished code. That is stated rather than hidden, and the readme is explicit about the project's maturity, calling itself a young library under heavy development and noting that every public interface is subject to change in the future.
What softens that is a fourth subpackage that does not appear in the two-group split at all: high-level plotting interfaces are also offered as a backend for a much more widely used plotting library, so there is a migration path for the second group that does not go through the experimental layer.
It is also worth noting what the project considers stable, which is not the plotting layer.
Two subpackages are marked relatively stable, one is marked experimental, one has no note
The structure section labels its own parts by maturity, and reading the labels is more useful than reading the descriptions.
The first is the application layer, which integrates an event system and offers a unified interface on top of many window backends. It is marked as having a relatively stable API. That is the layer that makes the library feel like a normal Python tool: you get events, a canvas, and keyboard handling without writing that yourself.
The second is the low-level graphics interface, a Pythonic object-oriented interface to the graphics API, also marked relatively stable. This is the layer the readme tells the OpenGL-fluent group to use, and its value proposition is that the underlying API's complexity is absorbed rather than passed through.
The third is the scene system, described as the system underlying the upcoming high-level interfaces, and marked as under heavy development and still experimental. The readme says it contains several modules, and then names them.
The fourth is high-level plotting, with no stability annotation at all. Its omission next to three explicit labels reads as deliberate: the readme is telling you there is nothing to say about its stability yet.
The summary line at the end of the section repeats the caveat in stronger terms, saying the API of all public interfaces is subject to change in the future although the two named packages are relatively stable at this point. The adverb does a lot of work in that sentence, since relatively stable in a project at version zero point seventeen is a narrower promise than it sounds.
The window backend list still names a toolkit generation that ended years ago
The application layer's selling point is a unified interface over many window backends, and the readme names them: a Qt binding, a wx binding, a standalone OpenGL context library, the Jupyter notebook environment, and others.
The Qt entry is the one to notice. It names the fourth generation of that toolkit, which reached end of life years before the last commit in this repository, which is dated within the last week. Not in an archived file or a historical section: in the structure description of a subpackage marked relatively stable.
That single word makes the sentence imprecise rather than wrong. The layer does support current Qt versions, and the packaging metadata offers extras for two successive generations of two different Qt binding families, plus a third toolkit entirely. So the capability is there.
But the readme is the document a new contributor reads to decide where to put their code, and an entry naming an end-of-life generation in a list of supported backends is either stale or a legacy compatibility claim the reader cannot distinguish from the other case. Either way it costs a moment of doubt about the rest of that section.
It is a small thing, and it is the kind that normally gets fixed the next time somebody edits the file for an unrelated reason. The reason it is worth writing down is that this file is otherwise unusually candid, so a reader calibrates their trust on the rest of it and then hits this.
The packaging metadata is more careful, listing current binding extras by name and generation rather than by toolkit brand.
The scene system runs its transforms on both the CPU and the GPU
The experimental subpackage is described in more detail than any other, and the detail is worth having even if you cannot depend on the code yet.
Four concepts are named. Visuals are graphical abstractions representing two-dimensional shapes, three-dimensional meshes and text, which is the object model. Transforms implement two and three dimensional transformations, and the readme states they are implemented on both the processor and the graphics processor. Shaders implement a composition system for plumbing together snippets of shader language code. And a scene graph tracks all objects within a transformation graph.
The processor and graphics processor duality on transforms is the interesting claim, because it is what lets the same scene description run in two places. A visualisation can be composed and inspected without a graphics context at all, and then executed with the work pushed to the hardware. That is the mechanism behind the offscreen rendering support elsewhere in the project, and behind using the library in a notebook where there is no window.
The shader description is unusually blunt for a graphics library. Calling it plumbing together snippets rather than a shader language or a material system tells you it is a concatenation layer rather than a compilation environment, which is a simpler and more predictable thing and also a more limited one.
What is not said is anything about how the two implementations stay in agreement. Whether the processor path and the graphics path are tested against each other, and what happens when they diverge, is exactly the kind of detail a caller of an experimental layer needs and the readme does not provide.
Four libraries merged into one, and three of them are still the obvious alternatives
The genesis section is one paragraph long and unusually specific, and it explains a lot about the project's shape.
It began when four developers, each with their own visualisation library, decided to work together. All four predecessors are named and linked: a Qt-based plotting library, a scientific visualisation library, one named after a character, and one built on a modern graphics interface.
Two things follow from that. The first is that this was a consolidation, not a new design. The four libraries overlapped heavily and competed for the same users, and the merged project inherited four sets of idioms, which is part of why four subpackages with three stability levels exist at all.
The second is that the predecessors are still separate, maintained projects, and at least one of them is far more widely used than VisPy today. Someone who reads the genesis section and concludes they should use one of the founders' libraries instead has reached a defensible conclusion from four links in the readme.
There is a third consequence that is only visible in the search data rather than the readme. A large share of the questions people ask about this project's name are about an unrelated person who shares it, covering subjects with nothing to do with graphics. The name is a common word in at least one other language, and for a scientific library with a two-word name that is a real and ongoing cost: someone looking for a person, a tool and a library all type the same two words.
The repository does nothing about that beyond existing, and it is not a defect. It does mean the project's name is a poor search identifier, which is worth knowing before anyone concludes that a lack of search results means a lack of adoption.
Governance runs four documents deep and none of them is in the repository
The governance section is longer than the structure section, which tells you something about how this project is run.
The layer closest to the code is a consensus model among the maintainers, which makes decisions about the project. That model is described in more detail on a governance page on the project website, and the maintainers themselves are listed on a second page.
Then there is a layer above it. Beyond decisions about the project itself, there is a steering committee for the overall organisation, described on a third page, along with an organisational charter and what the readme calls other related documents linked in that charter.
So: four documents, at three levels of authority, none of them in the repository.
What is in the repository is the code of conduct, and the readme explains what it contains, naming the expectations, the penalties for violating them, and how violations are reported to the people responsible for enforcing it. There is also a contributor covenant badge in the header pointing at that same file.
The arrangement is more formal than most scientific libraries manage, and for a project whose governance explicitly includes a charter it is coherent. The practical effect on a contributor is that the rules are discoverable but not versioned: a governance page can change without appearing in the repository history, and a pull request cannot point at a line of the charter it is trying to satisfy.
For a project at version zero point seventeen with an experimental core, having the organisational scaffolding settled before the code is finished is a defensible order of work, and it is also the kind of thing that is easy to mistake for a project further along than it is.
A version solver and a colour-space library are runtime dependencies
There are five runtime dependencies, and two of them would not appear on most plotting libraries' lists at all.
The array library is expected. A font rendering binding is the second, and it is there because the visual system renders text, so text support is not optional.
The third is a library implementing a perceptually uniform colour space conversion. That is a real feature rather than an oddity: converting between colour representations through a perceptually uniform space is what makes gradients and palettes behave predictably instead of going muddy in the middle. It also means every install, including the one where you only want a scatter plot, pulls in that library.
The fourth is the dependency that stands out. It is a version solver, the kind of tool a continuous integration system uses to pick a compatible set of package versions across platforms. It is a build-time concern by nature, and it is listed as a runtime dependency, so it is installed for everyone who installs the library.
That is the kind of thing that happens when a build requirement drifts into the install list, and the fix is trivial while the cost is a few megabytes and one more transitive dependency tree for every user.
The fifth is a packaging utilities library, which is unremarkable.
The build requirements are a separate and more demanding story, which the next section covers, because building this from source is a different proposition from installing it.
Building from source compiles extensions, and the archive has a DOI
The build configuration tells you that this is a compiled package, not a pure-Python one, and it says so with four build backends rather than one.
The build requires a modern build frontend, a plugin that derives the version from version control, a plugin that compiles extensions, and setuptools. It also requires a minimum version of the array library and a minimum version of the extension compiler, and the comment beside that array requirement links to the array library's own guidance about a specific major version.
That comment is the tell. Consulting an upstream migration guide during a build is what you do when a dependency made a breaking major release and every package in the ecosystem has to decide what it does about it. Whoever set that floor read that guidance and encoded the answer here.
Two consequences for anyone installing. One, a source install compiles extensions and therefore needs a working toolchain, which is a different experience from a wheel install. Two, the array requirement is a build-time floor, so a runtime constraint that the documentation would lead you to expect is actually enforced at compile time.
Two other things in the repository are worth noticing. There is a citation file and an archive badge carrying a persistent identifier, which is how research software becomes citable and how an archived snapshot stays resolvable. And the project is developed inside an integrated development environment it configures itself for, which tells you the development loop is a desktop application rather than an editor and a terminal.
The examples directory, meanwhile, is organised by layer rather than by topic: separate directories for the low-level interface, the scene system, plotting, notebooks, plus basics, a demo set, collections, a tutorial, a benchmark suite and offscreen rendering.
Editorial conclusion
vispy suits someone who already writes shader code, or who needs to visualise datasets far larger than a plotting library can hold, and for the second group the offscreen rendering and benchmark examples are the parts to read first. Four things to check first. Which of the four subpackages you are building on, because the readme marks two as relatively stable, one as experimental and under heavy development, and says every public interface is subject to change. Which window toolkit you will depend on, since the backend list spans two generations of two binding families plus a third toolkit, and the choice is pushed to install time. Whether you can run it without a display, since a headless workflow is not the default path. And whether your colour handling matters to you, because a perceptually uniform colour conversion library is a hard runtime dependency. Treat the readme as honest about its own maturity, which is rarer than it should be.
Frequently asked questions
What is VisPy used for?
High-performance interactive two and three dimensional data visualisation in Python, using the computational power of graphics processors through OpenGL to display very large datasets. The readme lists applications including interactive scientific plots with millions of points, direct visualisation of real-time data, interactive three dimensional models including meshes and volume rendering, OpenGL demonstration scenes, and scientific graphical interfaces with scalable widgets through a Qt binding or an IPython notebook with WebGL.
Is VisPy still maintained?
The dates say so: the last push is dated 2026-10-01, and the three recorded releases are 2026-09-08, 2026-05-20 and 2026-01-07, a cadence of roughly four months. The project classifies itself as alpha in its packaging metadata and calls itself a young library under heavy development, noting that all public interfaces are subject to change with two of four subpackages described as relatively stable.
How do I install VisPy?
The readme contains no install command and directs you to a dedicated installation page on the project website. The packaging metadata shows the Python floor is 3.10 and that the build itself requires a recent array library and the Cython extension compiler, so installing from source compiles extensions. Backend selection is done through extras, one per widget toolkit binding and generation.
Is VisPy difficult to learn?
The readme divides its audience in two and answers both. If you know OpenGL or are willing to learn it, it says you can already start, using the low-level interface so you write shader code instead of the underlying graphics API. If you do not know OpenGL, you are the audience for the high-level plotting interfaces, which the same readme describes as very basic, experimental and under heavy development.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/vispy-vispy)