ParaView Logo inside a Hexagon

Python state files in ParaView are used to create reproducible and editable visualization pipelines. Especially for applications like Catalyst, these state files are intended to be readable, modifiable, and adaptable to different workflows.

However, these files have not always been easy to read, interpret, and edit. Take creating a Clip filter as an example:

# create a new 'Clip'
clip1 = clip(registrationName='Clip1', Input=wavelet1)
clip1.ClipType = 'Plane'
clip1.HyperTreeGridClipper = 'Plane'
clip1.Scalars = ['POINTS', 'RTData']
clip1.Value = 157.0909652709961

Example snippet of a Python state file using default clip settings in ParaView 5.13

The above snippet showcases several properties that are not relevant for the selected settings. The Value property appears to have an effect on the clipping plane, which may tempt users to edit it and expect a change. However, Value is only relevant if the ClipType is set to Scalars, where the data is clipped by a scalar value. Value is not used at all otherwise.

Likewise, HyperTreeGridClipper is only relevant for hyper tree grid data structures. And, when any *modified* properties is selected in the Python state options, default settings such as ClipType = ‘Plane’ are not supposed to be written out, since that is the default (and thus was not “modified”).

Several properties have often appeared which are not even modifiable properties. For example:

renderView1.AxesGrid = 'Grid Axes 3D Actor'
renderView1.LegendGrid = 'Legend Grid Actor'
renderView1.PolarGrid = 'Polar Grid Actor'

Unmodifiable properties, in which only one value is currently allowed and that value is set, appearing in a Python state file in ParaView 5.13

These kinds of issues have pervaded several sections of the ParaView Python state files (see the representation below for a particularly noteworthy example), making them more challenging to read, interpret, and edit.

Yet another notable issue is that selecting a non-default colormap could easily create a wall of values in the state file, like so:

[Fig Old-Colormap] Inferno (matplotlib) colormap settings in a Python state file using ParaView 5.13.

… many more lines after this …
Inferno (matplotlib) colormap settings in a Python state file using ParaView 5.13

The wall of values not only makes the rest of the state file more difficult to read, but also makes editing the colormap itself nearly impossible!

Starting in ParaView 6, we are happy to announce that Python state files are significantly more readable, editable, and intuitive!

Enhancements

For a long time, the ParaView GUI has been aware of which properties are currently “relevant,” and which are not. The application shows/hides or enables/disables properties based upon that. This is defined, in technical terms, through the “property decorators” in the ParaView XML files.

For example, the Value of a clip function does not appear in the ParaView GUI unless the clip type is set to Scalars, because of these property decorators.

Starting in ParaView 6.0, a refactor of the property decorator code has enabled us to use these “relevance” specifications while creating Python state files as well! Now there is a new option within the Python State Options (which appears while saving a Python state file) that utilizes this.

Python State Options in ParaView 6.0 showcasing the new property saving option.

Only *actively used* modified properties is a new property saving option, and is also the new default setting. If selected, any properties that are hidden/disabled in the GUI due to the current settings will also not be written to the Python state file. This prevents irrelevant options from appearing, such as the Value when the clipping plane type is not Scalar, as demonstrated in the clip example earlier.

Another improvement to Python state files is that they now utilize the Set() function in order to facilitate reading blocks of properties. For example, the following in ParaView 5.13:

renderView1.ViewSize = [2000, 1000]
renderView1.CameraPosition = [0.0, 0.0, 50.0]
renderView1.CameraViewUp = [0.0, 0.5, 0.5]

Now appears like so in ParaView 6.0:

renderView1.Set(
    ViewSize=[2000, 1000],
    CameraPosition=[0.0, 0.0, 50.0],
    CameraViewUp=[0.0, 0.5, 0.5],
)

Catalyst state files were simplified by excluding features that are irrelevant to them. For example, lines that created and assigned layouts were removed from the state files since layouts are not relevant to Catalyst. Likewise, lines for creating animations were also removed (starting in ParaView 6.1), since they are also not relevant to Catalyst.

Additionally, numerous improvements to default value detection were made, so that most properties that now appear in Python state files are truly “modified” properties. Those improvements include:

  • ‘None’ strings are now properly detected as being default
  • Numerous XML defaults were set/updated to reflect their true defaults
  • Proxy properties now correctly keep track of their default properties
  • Certain properties, such as 2D transfer functions, which used to always appear in the state files even when unused, now only appear when they are actually being used

Finally, we also fixed the colormap code so that, when possible, a colormap preset name and rescale range (min and max) are used rather than writing out all of the values. Now, all values are only written out when the user has made custom modifications to the colormap (aside from just rescaling the min/max range). Examples of these can be seen in colormap section below.

Notable examples

Representations

When included, the representation settings were always quite verbose in ParaView 5.13. The following shows all of the representation settings that would be written out just for creating a wavelet and then immediately saving a Python state file:

wavelet1Display.Representation = 'Outline'
wavelet1Display.ColorArrayName = ['POINTS', '']
wavelet1Display.SelectNormalArray = 'None'
wavelet1Display.SelectTangentArray = 'None'
wavelet1Display.SelectTCoordArray = 'None',
wavelet1Display.TextureTransform = 'Transform2'
wavelet1Display.OSPRayScaleArray = 'RTData'
wavelet1Display.OSPRayScaleFunction = 'Piecewise Function'
wavelet1Display.Assembly = ''
wavelet1Display.SelectBlockSelectors = ['']
wavelet1Display.SelectOrientationVectors = 'None'
wavelet1Display.ScaleFactor = 2.0
wavelet1Display.SelectScaleArray = 'RTData'
wavelet1Display.GlyphType = 'Arrow'
wavelet1Display.GlyphTableIndexArray = 'RTData'
wavelet1Display.GaussianRadius = 0.1
wavelet1Display.SetScaleArray = ['POINTS', 'RTData']
wavelet1Display.ScaleTransferFunction = 'Piecewise Function'
wavelet1Display.OpacityArray = ['POINTS', 'RTData']
wavelet1Display.OpacityTransferFunction = 'Piecewise Function',
wavelet1Display.DataAxesGrid = 'Grid Axes Representation'
wavelet1Display.PolarAxes = 'Polar Axes Representation'
wavelet1Display.ScalarOpacityUnitDistance = 1.7320508075688774
wavelet1Display.OpacityArrayName = ['POINTS', 'RTData']
wavelet1Display.ColorArray2Name = ['POINTS', 'RTData']
wavelet1Display.IsosurfaceValues = [157.0909652709961]
wavelet1Display.SliceFunction = 'Plane'
wavelet1Display.Slice = 10
wavelet1Display.SelectInputVectors = [None, '']
wavelet1Display.WriteLog = ''

Representation settings for simply creating a wavelet and writing out a Python state file in ParaView 5.13, using the default Python state options. These settings would be written out every time, regardless of which settings were relevant or modified.

Many of the settings shown above are not relevant for simply displaying an outline, and even some of them (such as PolarAxes and DataAxesGrid) are not even modifiable – they only have one possible value! The large number of irrelevant options would make it challenging for users to parse and determine which options are important and which ones they should actually modify.

The variety of improvements, including hiding irrelevant options when the new write setting is selected, and improved default value detection, resulted in the representation settings being simplified to the following:

wavelet1Display.Set(
    Representation='Outline',
    ColorArrayName=['POINTS, ''],
)

New representation settings for just creating a wavelet and immediately writing out a Python state file in ParaView 6.0, using the default Python state options.

These are thus the current base settings which appear when nothing is modified after creating and displaying a wavelet. When any property of the representation is modified in the GUI, it would appear here and be much easier to spot. These fixes likewise apply to all other representation types as well.

Colormaps

Rather than writing out a wall of values in the colormap section of the Python state file (as shown above), ParaView now writes out code such as this:

tempLUT.Set(
    RGBPoints=GenerateRGBPoints(
        preset_name='Inferno (matplotlib)',
        range_min=293.1499938964844,
        range_max=913.1500244140625,
    ),
    ScalarRangeInitialized=1.0,
)

New colormap code in Python state files in ParaView 6.0

A colormap preset name is specified, along with a min/max for rescaling the colormap range. This is substantially easier for users to read, edit, and adapt for their current workflow.

If the colormap was manually edited by the user in the GUI, such that it cannot be simply regenerated using a colormap preset name and min/max range, ParaView falls back to writing out all values. However, these values are also now formatted to be more readable than before. For example:

rtDataLUT.Set(
    RGBPoints=[
        # scalar, red, green, blue
        37.35310363769531, 0.05639999999999999, 0.05639999999999999, 0.47,
        78.4452792808878, 0.24300000000000013, 0.4603500000000004, 0.81,
        108.8345671401086, 0.3568143826543521, 0.7450246485363142, 0.954367702893722,
        140.83744550512927, 0.6882, 0.93, 0.917909999999999,
        157.0909652709961, 0.8994959551205902, 0.944646394975174, 0.7686567142818399,
        178.21895888948117, 0.957107977357604, 0.8338185108985666, 0.5089156299842102,
        211.4317321773438, 0.9275207599610174, 0.6214389091739178, 0.31535705838676426,
        240.3421933627566, 0.8, 0.3520000000000001, 0.15999999999999998,
        276.8288269042969, 0.59, 0.07670000000000013, 0.11947499999999994,
    ],
    ColorSpace='RGB',
    ScalarRangeInitialized=1.0,
)

Colormap definition in a Python state file after manually editing a “Fast” colormap in ParaView 6.0

Render View

All of the changes greatly simplified the render view settings:

# Create a new 'Render View'
renderView1 = CreateView('RenderView')
renderView1.ViewSize = [2153, 1113]
renderView1.AxesGrid = 'Grid Axes 3D Actor'
renderView1.StereoType = 'Crystal Eyes'
renderView1.CameraPosition = [0.0, 0.0, 66.92130429902464]
renderView1.CameraFocalDisk = 1.0
renderView1.CameraParallelScale = 17.320508075688775
renderView1.LegendGrid = 'Legend Grid Actor'
renderView1.PolarGrid = 'Polar Grid Actor'

Render view section of a ParaView Python state file in ParaView 5.13

# Create a new 'Render View'
renderView1 = CreateView('RenderView')
renderView1.Set(
    ViewSize=[1470, 873],
    CameraPosition=[0.0, 0.0, 66.92130429902464],
)

Render view section of a ParaView Python state file in ParaView 6.1

Clip

The clip example shown at the beginning is now simplified to just one line:

# create a new 'Clip'
clip1 = Clip(registrationName='Clip1', Input=wavelet1)

Clip section of a Python state after saving using all default settings in ParaView 6.0

Future Plans

Most of these enhancements are already available in ParaView 6.0, the latest release. A few more enhancements be coming in the next upcoming release, ParaView 6.1.

There are additionally still more improvements we are able to make, and we plan to continue improving the simplicity and readability of ParaView Python state files in the near future.

Leave a Reply