Animations from scientific data using Paraview 4.3 and python

2015-04-05
#paraview #python #ubuntu #howto

§ Create frames

This note describes the usage of Paraview 4.3 (in contrast to the previous note with Paraview before 4.1). Some changes were made:

  • command-line arguments were added to make the code more reusable
  • it works with Paraview extracted from the archive (4.3.1)
  • the white background must be specified manually (SetViewProperties(view, Background = [1, 1, 1]) in the code)

The script is tested under Ubuntu 14.04 with Paraview 4.3.1. Paraview was downloaded from the official site and extracted to /home/bikulov/bin/ParaView-4.3.1-Linux-64bit/lib/paraview-4.3 (you have to change this line in the script to your destination). The state file must be prepared in the same Paraview 4.3.1 to avoid compatibility issues (or you may get errors about ColorArrayName).

Script (also available as a gist):

 1#!/usr/bin/env python
 2
 3import os, sys
 4import glob, natsort, argparse
 5
 6ParaviewPath="/home/bikulov/bin/ParaView-4.3.1-Linux-64bit/lib/paraview-4.3"
 7print("export LD_LIBRARY_PATH={ParaviewPath}:$LD_LIBRARY_PATH".format(ParaviewPath=ParaviewPath))
 8
 9sys.path.append(os.path.join(ParaviewPath, "site-packages"))
10sys.path.append(os.path.join(ParaviewPath, "site-packages/vtk"))
11from paraview.simple import *
12
13def main(pipeline, state, files, output):
14    filenames = natsort.natsorted(files)
15    servermanager.LoadState(state)
16    view = servermanager.GetRenderView()
17    camera = view.GetActiveCamera()
18    phase = FindSource(pipeline)
19
20    # Set white background
21    SetViewProperties(view, Background = [1, 1, 1])
22
23    try:
24         os.makedirs(output)
25    except:
26        pass
27
28    imgNum = 0
29
30    for f in filenames:
31        phase.FilePrefix = f
32        phase.FileNameChanged()
33        view.WriteImage(os.path.join(output, str(imgNum).zfill(6) + ".png"), "vtkPNGWriter", 1)
34        imgNum += 1
35
36if __name__ == "__main__":
37    parser = argparse.ArgumentParser(prog="PROG", description="Draw With Paraview")
38    parser.add_argument("--state", type=str, help="State file to load", default="state.pvsm")
39    parser.add_argument("--pipeline", type=str, help="Pipiline name for changing file", default="data")
40    parser.add_argument("--output", type=str, help="Output path for images", default="img")
41    parser.add_argument("files", nargs="*", help="Files to be used in the pipeline")
42
43    args = parser.parse_args()
44
45    main(pipeline=args.pipeline, state=args.state, files=args.files, output=args.output)

Command-line arguments explanation:

  • --state is the filename with the state to be loaded (File->Save State in Paraview)
  • --pipeline is the name of the pipeline inside the state (the item in the Pipeline browser for which you want to change the File Prefix)
  • --output is the path to the directory where the images will be saved
  • files are a bunch of raw binary images you want to visualize as a video

Example run (it will process all *-phase.raw files in the directory and save the resulting images into the imgtest directory):

1./draw_with_paraview.py --state state.pvsm --pipeline data --output imgtest *-phase.raw

Note: you must add the path to the Paraview libraries in LD_LIBRARY_PATH before running (the script prints this line out for convenience):

1export LD_LIBRARY_PATH=/home/bikulov/bin/ParaView-4.3.1-Linux-64bit/lib/paraview-4.3:$LD_LIBRARY_PATH

§ Postprocess frames

You may want to crop the images in the output folder. For mp4, the width and height must be divisible by two, so you may need to crop them accordingly (in parallel for speed):

1img=$(ls *.png|head -n 1)
2width=$(($(identify -format "(%[fx:w]/2)*2" ${img})))
3height=$(($(identify -format "(%[fx:h]/2)*2" ${img})))
4find -name '*.png' -exec mogrify -crop "${width}x${height}+0+0" {} +

Or the same commands in one line:

1img=$(ls *.png|head -n 1); width=$(($(identify -format "(%[fx:w]/2)*2" ${img}))); height=$(($(identify -format "(%[fx:h]/2)*2" ${img}))); find -name '*.png' -exec mogrify -crop "${width}x${height}+0+0" {} +

You may also need to crop the images to a specific size; just use the final line:

1find -name '*.png' -exec mogrify -crop <width>x<height>+<x_shift>+<y_shift> {} +

§ Create animation from the frames

Create the video from the images (ffmpeg is no longer supported, so use avconv):

1avconf -qscale 1 -r 20 -b 9600 -i %06d.png output_file.mp4