Kitware Source Feature Article: July 2009

ParaView and Python

In this document, we will cover the basics of using ParaView’s Python interface. Please note that this text is based on ParaView 3.6 and higher and is not directly applicable to earlier versions. This document only touches on the basic concepts of ParaView’s Python interface. For more details and examples, see the ParaView Wiki and search for “Python Scripting” or “Python Recipes”.

ParaView offers rich scripting support through Python. This support is available as part of the ParaView client (paraview), an MPI-enabled batch application (pvbatch), the ParaView python client (pvpython) or any other Python-enabled application. Using Python, users and developers can gain access to the ParaView engine called Server Manager.

Getting Started
To start interacting with ParaView through Python, you have to load the paraview.simple module. This module can be loaded from any Python interpreter as long as the necessary files are in PYTHONPATH. These files are the shared libraries located in the paraview binary directory and as python modules in the paraview directory: paraview/simple.py, paraview/vtk.py, etc. You can also use either pvpython (for stand-alone or client/server execution), pvbatch (for noninteractive, distributed batch processing) or the Python shell invoked from Tools->Python Shell using the ParaView client to execute Python scripts. You do not have to set PYTHONPATH when using these.

In this document, I will be using the Python integrated development environment, IDLE. My PYTHONPATH is set to the following:

/Users/berk/work/paraview3-build/bin:/Users/berk/
work/paraview3-build/Utilities/VTKPythonWrapping

This is on my Mac and uses the build tree. In IDLE, let’s start by loading the servermanager module.

>>> from paraview.simple import *

In this example, we will use ParaView in stand-alone mode. Connecting to a ParaView server running on a cluster is covered later.

Creating a Pipeline
The simple module contains many functions to instantiate readers, filters and other related objects. You can get a list of objects this module can create from www.paraview.org/ OnlineHelpCurrent/.

Let’s start by creating a reader object to read a VTK file.

>>> vtkreader = LegacyVTKReader()

You can get some documentation about the cone object using help().

>>> help(vtkreader)

Help on LegacyVTKReader in module paraview.servermanager object:

class LegacyVTKReader(SourceProxy)

The Legacy VTK reader loads files stored in VTK’s legacy file format (before VTK 4.2). The expected file extension is .vtk. The type of the dataset may be structured grid, uniform rectilinear grid (image/ volume), non-uniform rectilinear grid, unstructured grid, or polygonal. This reader also supports file series. The data descriptors are defined in FileNames. FileNames is the list of files to be read by the reader. If more than 1 file is specified, the reader will switch to file series mode in which it will pretend that it can support time and provide 1 file per time step. TimestepValues indicate the available timestep values.

This gives you a full list of methods and properties (data descriptors). When using ParaView’s Python interface, we interact with objects by reading and setting their properties. Let’s start by setting the name of the file to be read.

>>> vtkreader.FileNames =
       [“.../VTKData/Data/office.binary.vtk”]

Note that we used a file from the VTKData repository. VTKData is a separate download from the download page on VTK.org. This file contains a uniform grid that has the numerical solution of the air flow in an office. Also note that the property is called FileNames rather than FileName and expects a Python list. This is because the VTK reader in ParaView can read a series of files that represent a time series.

Alternatively, we could have specified the file name when creating the object.

>>> vtkreader = = LegacyVTKReader(FileNames =
       [“.../VTKData/Data/office.binary.vtk”])

The constructor functions in paraview.simple all accept an arbitrary number of key,value pairs that represent property names and values.

We can read the property value back.

>>> vtkreader.FileNames
       [‘/Users/berk/Work/VTKData/Data/office.binary.vtk’]

Now that we set the file name, we can access the metainformation about the data it contains. For example, we can get a list of point (node) centered data arrays by accessing the PointData property:

>>> vtkreader.PointData[:]
vtkFileSeriesReader : [ ........... ]
[Array: scalars, Array: vectors]

Note that before the function returned a value, “vtkFile-SeriesReader : [ ........... ]” appeared on the output. This is because ParaView forced the reader to execute and read data from the file so that it can give us the metadata. The paraview.simple module forces readers and filters to execute when necessary to always produce up-to-date metadata. This file contains two arrays: scalars and vectors. We can get the range of the scalar array as follows.

>>> vtkreader.PointData[“scalars”].GetRange()
(-3.8695590496063232, 0.71856027841567993)

Now that we know the range of the scalar’s array, let’s extract some isosurfaces.

>>> c = Contour(vtkreader)
>>> c.ListProperties()
[‘ComputeGradients’, ‘ComputeNormals’,
 ‘ComputeScalars’, ‘Isosurfaces’, ‘Input’,
 ‘ContourBy’]
>>> c.ComputeScalars = True
>>> c.Isosurfaces = [-2, 0]

Here, we used the ListProperties() method to find the Isosurfaces method. We also set ComputeScalars on so that the output contains the contour value as a scalar.

Rendering
Next, we will display the outline of the data as well as the isosurfaces. First, let’s display the output of vtkreader as an outline.

>>> Show(vtkreader)
<paraview.servermanager.GeometryRepresentation object at 0xaf6de50>
>>> SetDisplayProperties(vtkreader,
Representation=’Outline’)

Note that we used SetDisplayProperties() to set the representation type of vtkreader. We could have done the following instead.

>>> dp = GetDisplayProperties(vtkreader)
>>> dp.Representation = ‘Outline’

Let’s also turn on the visibility of the isosurfaces and render.

>>> Show(c)
vtkContourFilter : [ ........... ]
<paraview.servermanager.GeometryRepresentation object at 0x293110>
>>> dp.ColorArrayName = ‘scalars’
>>> dp.LookupTable = MakeBlueToRedLT
(-3.8695590496063232, 0.71856027841567993)
>>> GetActiveCamera().Elevation(105)
>>> Render()
vtkPainterPolyDataMapper : [ ........... ]
<paraview.servermanager.RenderView object at 0x20e60030>

Note, we set the color of the isosurface to be mapped from the scalar’s array. We also created a lookup table that is used for this mapping (MakeBlueToRedLT). This lookup table interpolates color from blue to red in the given range. We also moved the camera by 105 degrees using the Elevation() method. Finally, Render() renders the scene.

We can capture this window as an image as follows.

>>> WriteImage(“/Users/berk/test.png”)

The resulting image is shown below.

ParaView Image

Finally, we can save the state of ParaView to load later.

>>> servermanager.SaveState(“.../state.pvsm”)

Using the Python Shell in ParaView
Let’s continue our tutorial inside the ParaView user interface. Quit Python and start ParaView. First load the state file we just saved using File->Load State. Next, bring up the Python shell using Tools->Python Shell. You will notice that we no longer have access to variables we defined in our previous session (vtkreader, c and dp). So, how do we access the objects that were in the state? Paraview.simple has two convenience methods that makes this easy.

>>> GetSources()
{(‘Contour1’, ‘1520’): <paraview.servermanager.
  Contour object at 0x24830110>,
(‘LegacyVTKReader1’,
 ‘994’): <paraview.servermanager.LegacyVTKReader
 object at 0x248302b0>}
>>> c = FindSource(“Contour1”)

GetSources() returns a Python dictionary that has references to all pipeline objects as well as their names. FindSource() finds an object given its name. You can find the name of the object in the pipeline browser.

Next, let’s delete the contour filter.

>>> Delete(c)

You will notice that the contour object is also removed from the pipeline browser. This is because both the user interface and the Python interpreter modify the same underlying engine and all changes made in one are immediately reflected by the other.

Client/Server Scripting
Let’s now switch back to the Python shell and explore how to connect to a ParaView server. Feel free to skip this section if you are not running ParaView in client/server mode.

First, start a ParaView server (pvserver) either on the local machine or on a remote server. I ran pvserver on my desktop for this example.

You can use the Connect() function to connect to a server.

>>> from paraview.simple import *
>>> Connect(“localhost”, 11111)
Connection (localhost:11111)

Here, the first argument is the hostname and the second argument is the port number. The easiest way to get started is to load the state we previously saved.

>>> servermanager.LoadState(“/Users/berk/state.pvsm”)
>>> SetActiveView(GetRenderView())

Note that I had to set the active view manually as ParaView does not currently save the active objects in the state. We will fix this in the next release. Loading a state saved by a stand-alone ParaView application using a client/server ParaView works without problems as ParaView creates the appropriate objects under the cover. Everything discussed in this article should work without any modifications.

Acknowledgements
This work has been partially funded by Sandia National Laboratories through contract number DE-AC04-94AL85000.

Berk Geveci Berk Geveci is Kitware’s Director of Scientific Computing where he leads the scientific visualization and informatics teams. He is one of the leading developers of the ParaView visualization application and the Visualization Toolkit (VTK). His research interests include large scale parallel computing, computational dynamics, finite elements and visualization algorithms.