A visualization code for gravitational wave data I created in 2020 with Python and ParaView, published under the MIT license.

This Python package uses the ParaView scientific visualization toolkit to produce 3D renderings of gravitational wave data from a numerical simulation or a waveform model.

From in the nilsvu/gwpv GitHub repository:



This Python package uses the ParaView scientific visualization toolkit to produce 3D renderings of gravitational-wave data from a numerical simulation or a waveform model.

Try it now:

docker run -v $PWD:/out nilsleiffischer/gwpv:latest \
  scene Examples/Rainbow/Still.yaml -o /out

Table of contents


Option 1: Pre-built Docker container

  1. Install Docker.
  2. docker run nilsleiffischer/gwpv:latest

Docker will pull the latest pre-built image and run it. The container runs the entrypoint automatically (see Usage). To output rendered frames and load data from your system you can mount directories using Docker’s -v option. Try rendering one of the example scenes:

docker run -v $PWD:/out nilsleiffischer/gwpv:latest \
  scene Examples/Rainbow/Still.yaml -o /out

Here we mount the current working directory $PWD as the directory /out in the container and use it to output frames. You can mount additional directories to make your scene configuration files and data available in the container (see Usage).

Option 2: Native environment

It is strongly recommended to use Python 3 for this program. In particular, parallel rendering may not work with Python 2 and setting up the environment with Python 3’s venv is more robust than Python 2’s virtualenv.

  1. Install ParaView. Prefer versions with Python 3. This program was tested thoroughly with ParaView version 5.8.
  2. Create a virtual environment with ParaView’s Python. With Python 3 you could do this:
    path/to/python3 -m venv path/to/new/env

    Make sure to set up the environment with the same Python installation that ParaView uses. If you are unsure, try this:

    # Start interactive ParaView Python shell
    # Output path to the Python executable
    >>> import sys
    >>> sys.executable

    On macOS the pvpython executable is typically located in /Applications/ The Python executable determined by the script above may be named vtkpython, in which case you can look for the python2 or python3 executable in the same directory or a bin subdirectory.

  3. Give ParaView access to the environment. If you have created the environment with Python 3’s venv then copy the scripts/ script to the environment:
    cp scripts/ path/to/new/env/bin

    Note that environments created with the virtualenv package include this script automatically and you don’t need to copy it. The script is used to activate the environment from within Python scripts. It allows ParaView’s Python to pick up the packages installed in the environment (see this blog post for details).

    You may also want to add the ParaView executables such as pvpython to your PATH when the environment is activated for convenient access. To do so you can append the following line to path/to/env/bin/activate as well:

    export PATH="path/to/paraview/bin/:$PATH"

    On macOS you may also need to append this line to pick up the paraview GUI executable:

    export PATH="path/to/paraview/MacOS/:$PATH"
  4. Install the following packages in the environment, making sure to use ParaView’s HDF5 when installing h5py:
    . env/bin/activate
    HDF5_DIR=path/to/paraview/hdf5/ pip install --no-binary=h5py h5py
    pip install [-e] path/to/this/repository

    Note that the HDF5_DIR should have include and lib directories with ParaView’s HDF5. On macOS it is typically /Applications/ Add the -e flag when installing this repository’s Python package to install it in “editable” mode, i.e. symlink instead of copy it so changes to the repository are reflected in the installation. On Python 2, pip install llvmlite==0.31.0 manually because later versions drop support for Python 2.


Try rendering one of the example scenes like this: scene Examples/Rainbow/Still.yaml -o ./

The rendered scene is a still frame defined by the configuration file Examples/Rainbow/Still.yaml. It is based on Examples/Rainbow/Rainbow.yaml which, by itself, defines a short movie: scene Examples/Rainbow/Rainbow.yaml \
  --render-movie-to-file ./Rainbow
  --num-jobs NUM_JOBS

Feel free to turn up NUM_JOBS to render the frames in parallel.

Compose configuration files to define a scene

A scene is defined by a stack of one or more YAML configuration files. The configuration files can be source-controlled and shared, so each visualization is reproducible. See Examples/Rainbow/Rainbow.yaml for an example of a scene configuration file.

Multiple configuration files can be stacked to compose a scene. Configurations in later files override those in earlier files. You find a collection of useful configuration files in the directory scene_overrides/. They are found automatically by, so you can, for example, easily adjust the background of the scene or the rendering resolution: \
  scene Examples/Rainbow/Still.yaml Background/Light Resolutions/High -o ./

Scene configuration files can specify that they always include others so you don’t have to build the composition stack on the command line:

  - Background/Light
  - Resolutions/High

You can also list scene compositions in a file such as Examples/Rainbow/Scenes.yaml:

  - Name: RainbowLight
      - Rainbow
      - Background/Light

You can sequentially render all scenes listed in such a file by calling the scenes entrypoint: scenes Examples/Rainbow/Scenes.yaml -o ./ --num-jobs NUM_JOBS

To render a single scene from the file, use the scene entrypoint and specify the name of the scene: scene Examples/Rainbow/Scenes.yaml:Rainbow -o ./ --num-jobs NUM_JOBS

Sometimes it can be useful to override particular configurations from the command line, for example to reduce the frame rate for a test rendering. To do so, you can pass key-value pairs of scene configuration options to like this: scene Examples/Rainbow/Rainbow.yaml -o ./ \
  --override Animation.FrameRate=1

The key of each override is parsed as the key-path into the scene configuration to replace, and its value is parsed as YAML.


To specify datasources for the rendered scenes, such as waveform data or horizon shapes from a simulation, the configuration file Examples/Rainbow/Rainbow.yaml includes Examples/Rainbow/Datasources.yaml.

Specifying the datasources in a separate configuration file allows excluding it from source control, e.g. to set local file system paths on a particular rendering machine.

Datasources can refer to a local file system path or a remote URL. They will be downloaded and cached, if needed. For example, you can pick any simulation from the SXS waveform catalog and use the URL to one of its public waveform data files:

    Subfile: Extrapolated_N2.dir
    Cache: ./waveform_data_cache

Explore waveform data in the ParaView GUI application

  1. We need to make ParaView aware of our Python environment and the plugins in this repository. This is easiest done from the command line. Before launching the ParaView GUI, make sure the Python environment is activated as described in Installation. Then launch ParaView like this:
    PV_PLUGIN_PATH=path/to/paraview_plugins path/to/paraview

    You will now find the plugins provided by this repository in the ParaView GUI when you select ‘Tools’ > ‘Manage Plugins’.

  2. Open a waveform data file in ParaView and select the Waveform Data Reader to load it. Waveform data files in SpEC’s output format are currently supported.
  3. Add the Waveform To Volume filter to the loaded data.
  4. Change the representation to Volume and adjust the following properties:
    • Volume Rendering Mode (try GPU Based and enable Shade)
    • Scalar Opacity Unit Distance (try a quarter of the domain size)
    • Transfer function (select Edit color map)

Here’s a few images and movies produces with this software package:


GW190412 PanoramaLargeScaleNoTail_frame.000023

GW190412 CloseupSlowdownWithSpins_frame.000003

GW190412 FaceOnMerger

  • Source: nilsleiffischer/gw190412-movie
  • More information and images available at: and
  • Video:

    GW190412 video

  • Selected media coverage:


GW190814 MergerFaceOnAllModes

GW190814 PanoramaModesCompositionFaceOn_frame.000003

GW190814 PanoramaAllModesFaceOn_frame.000006

  • Source: nilsleiffischer/gw190814-movie
  • More information and images available at: and
  • Video:

    GW190814 video

  • Selected media coverage:


GW190521 FaceOn.000003

GW190521 Serene

  • Source: nilsleiffischer/gw190521-movie
  • More information and images available at: and
  • Video:

    GW190521 video

  • Selected media coverage:

Licensing and credits

This code is distributed under the MIT license. Please see the LICENSE for details. When you use code from this project or publish media produced by this code, please include a reference back to the nilsleiffischer/gwpv repository.

Copyright (c) 2020 Nils Leif Fischer