ParaView: Python View is now more versatile

In ParaView 4.1, the Python View was capable of generating visualizations using matplotlib only. We recently made some changes to the Python View to make it possible to use just about any Python library to generate images displayed in the view. The only restriction on Python libraries that can be used for this purpose is that there must be a way to access pixel data from a plot generated by the library. Matplotlib plots are still fully supported in a backwards-compatible way, so no changes to existing Python View scripts are required to use the now more versatile Python View

In a previous blog post, we detailed using the Python View to plot data loaded into ParaView. At a high-level view, the Python View requires two functions to be defined in the Python script. One function, called setup_data(), is used to request data arrays in data objects that should be copied to the ParaView client. This step remains unchanged. The second function, called render() has a new signature that makes it more widely useful. That change is the subject of the rest of this post.

The new render() function signature

Previously, the render function had the signature

def render(view, figure)

where view was the Python View object of type vtkPythonView calling this function and figure was a matplotlib.figure.Figure object that was set up by the view automatically. The function was not expected to return a value.

Now, the render function has the signature

def render(view, width, height)

where view is still the vtkPythonView object and the width and height parameters are the width and height of the current render window in the view.

One of the most important changes to this function is that it is now expected to return a vtkImageData object containing the image content to display in the view render window. If no vtkImageData object is returned, the view window will be black.

Writing new Python View scripts that use matplotlib

No changes are necessary for Python View scripts used in ParaView 4.1 that define a render() function that takes a matplotlib.figure.Figure object as the second argument. However, for new matplotlib-based Python View scripts, we recommend using the new signature render(view, width, height).

If you want to use matplotlib for plotting while using the new signature for render(), your function needs to create a matplotlib.figure.Figure object internally to do the plotting. This can be done with some utility code in the python_view module.

from paraview import python_view
figure = python_view.matplotlib_figure(width, height)

This figure object can be used in the same way as the figure argument in the previous signature of the render() function.

After matplotlib plotting commands have been added, the figure must be converted to a vtkImageData object. A convenience function has been added to the python_view module to do this. It is used as follows:

from paraview import python_view
vtk_image = python_view.figure_to_image(figure)

The last step when using the new signature of the render() function is to return the vtkImageData:

return vtk_image

Pulling it all together, here is an example of a function with the new signature that generates a histogram of an array named 'X' associated with the point data in the first visible object in the pipeline browser:

def render(view, width, height):
  from paraview import python_view
  figure = python_view.matplotlib_figure(width, height)

  ax = figure.add_subplot(1,1,1)
  ax.minorticks_on()
  ax.set_title('Plot title')
  ax.set_xlabel('X label')
  ax.set_ylabel('Y label')

  # Process only the first visible object in the pipeline browser
  dataObject = view.GetVisibleDataObjectForRendering(0)

  x = dataObject.GetPointData().GetArray('X')

  # Convert VTK data array to numpy array for plotting
  from paraview.numpy_support import vtk_to_numpy
  np_x = vtk_to_numpy(x)

  ax.hist(np_x, bins=10)

  return python_view.figure_to_image(figure)

 

Generating views with numpy

An example of a library that can be used to generate images to be displayed in the Python View is numpy. Images in numpy may be defined as 3D arrays (height, width, color components). The python_view module provides a convenience function to convert numpy arrays to vtkImageData objects. As an example, the render() function below generates a solid red image to display in the view.

def render(view, width, height)
  import numpy
  cb = numpy.zeros((height, width, 4), dtype=numpy.uint8)
  cb[:,:,0] = 255 # Red channel
  cb[:,:,3] = 255 # Alpha channel

  from paraview.python_view import numpy_to_image

  return numpy_to_image(cb)

This is not a terribly interesting use of the Python View, but it illustrates a minimal example of using numpy to generate content for display in the view window.

Using other plotting libraries

A collection of Python libraries that could potentially be used in the Python View can be found here. Note that aside from matplotlib, the libraries listed on this page have not been tested with the Python View. We would love to hear if you use any of these libraries in the Python View.

Questions or comments are always welcome!