Visit scripting
This page briefly goes over Visit's python scripting interface, and shows some example visualization scripts.
Python scripting
Visit has a command line interface based on python. The python interface manual extensively documents the available python objects, but is not exceptionally useful functionally.
The most useful way I have been able to learn how to control certain actions and attributes with scripting is by using the commands window to record actions I perform interactively with the GUI interface. To open the commands window, go to Controls --> Command. If you press Record, take some actions like move the view around, and press Stop, the python commands corresponding to your actions will show up in the dialog box.
When you take an action, an excessive number of commands are usually printed in the dialog box. You will see commands enclosed in # Begin spontaneous state
and # End spontaneous state
tags each time you click in the visualization window. With trial and error you can distill these commands to what is really necessary.
Writing python scripts
I prefer to write VisIt scripts in an external text editor, like Atom. You could also write scripts in the Command window and run them with the Execute button. If you do write scripts here, you can ignore the next section.
In general, you will want to write the scripts locally, since the execution is started using VisIt running locally on your machine, and then it does the computations on the compute engine.
Running scripts
One way to run python scripts is through the built in command line interface.
Launch the command line interface: Controls --> Launch CLI
This will open a terminal on your local machine with the message VisIt: Message - Added a new client to the viewer.
and you will see a python prompt >>>
. The terminal probably uses your home directory as its default working directory. You can check this in python with
import os
os.getcwd() # prints current working directory. Equivalent to pwd in bash
Navigate to where your script is
os.chdir('path/to/visit/scripts')
And you can run the script you wrote by importing it
import my_visit_script_name
Alternatively, you could copy the script from your text editor into the command window and execute it there.
Examples
The example below plots a temperature contour plot and a pseudocolour plot of ice thickness. The ice thickness variable has been tiled to also be a 3D dataset.
import visit
import visit_utils
import os
make_movie = True # Flag to control whether to make animation or just render
# Dimensions of the model grid
nx = 250
ny = 250
nz = 50
# Number of *.nc files there are to plot
ntimes = 96
# Step size to pass through files. Files are slices as files[::step]
step = 1
# Video format for encoding
format = "mpg"
# Format to save still images as
stillname = "/Users/tghill/visit/solarforcing%04d.png"
visit.DeleteActivePlots()
visit.DeleteActivePlots()
# Add a temperature contour plot
visit.AddPlot("Contour", "T", 1, 1)
ContourAtts = visit.ContourAttributes()
ContourAtts.colorType = ContourAtts.ColorByColorTable
ContourAtts.colorTableName = "viridis"
ContourAtts.contourNLevels = 9
ContourAtts.minFlag = 1
ContourAtts.min = 0
ContourAtts.maxFlag = 1
ContourAtts.max = 2
ContourAtts.scaling = ContourAtts.Linear
visit.SetPlotOptions(ContourAtts)
# Add a seaice area fraction pcolor plot
visit.AddPlot("Pseudocolor", "SIheff", 1, 1)
patts = visit.PseudocolorAttributes()
patts.colorTableName = "bluehot"
patts.minFlag = 1
patts.min = 0
patts.maxFlag = 1
patts.max = 1
patts.opacity = 0.85
patts.legendFlag = 0
patts.opacityType = patts.Ramp
visit.SetPlotOptions(patts)
# Define the displacement operator for mapped topography
visit.DefineVectorExpression("grid", "{{0*zc, 0*zc, zc - coord(mesh{nx}x{ny}x{nz})[2]}}".format(nx = nx, ny = ny, nz = nz))
visit.SetActivePlots((0, 1))
visit.AddOperator("Displace", 1)
DisplaceAtts = visit.DisplaceAttributes()
DisplaceAtts.factor = 1
DisplaceAtts.variable = "grid"
visit.SetOperatorOptions(DisplaceAtts, 1)
# Set view attributes
View3DAtts = visit.View3DAttributes()
View3DAtts.viewNormal = (0.65, -0.55, 0.45)
View3DAtts.focus = (3500, 1500, -10)
View3DAtts.viewUp = (-0.411548, 0.319154, 0.85368)
View3DAtts.viewAngle = 30
View3DAtts.parallelScale = 3521.48
View3DAtts.nearPlane = -8343.87
View3DAtts.farPlane = 8343.87
View3DAtts.imagePan = (0, 0)
View3DAtts.imageZoom = 1.25
View3DAtts.perspective = 1
View3DAtts.eyeAngle = 2
View3DAtts.centerOfRotationSet = 0
View3DAtts.centerOfRotation = (2950, 2950, -500)
View3DAtts.axis3DScaleFlag = 1
View3DAtts.axis3DScales = (1, 1, 100)
View3DAtts.shear = (0, 0, 1)
View3DAtts.windowValid = 1
visit.SetView3D(View3DAtts)
# Adjust the lighting. Use 3 lights
light0 = visit.LightAttributes()
light0.enabledFlag = 1
light0.type = light0.Camera
light0.direction = (0, 0, -1)
light0.brightness = 0.6
visit.SetLight(0, light0)
light1 = visit.LightAttributes()
light1.enabledFlag =1
light1.type = light1.Camera
light1.direction = (-0.5, -0.5, -0.7)
light1.brightness = 0.5
visit.SetLight(1, light1)
light2 = visit.LightAttributes()
light2.enabledFlag = 2
light2.type = light2.Camera
light2.direction = (0.5, 0.5, -0.7)
light2.brightness = 0.5
visit.SetLight(2, light2)
# Pass through time steps, render, and save still frames
if make_movie:
# Only need to make the still frames once. Skip if they already exist
for j,ts in enumerate(range(0, ntimes, step)):
name = stillname % j
if not os.path.exists(name + ".png"):
# Set save attributes including filename
s = visit.SaveWindowAttributes()
s.family = 0
s.format = s.PNG
s.width, s.height = 4000, 2000
s.quality = 100
s.fileName = name
visit.SetSaveWindowAttributes(s)
# Move time slider, render, and save
visit.TimeSliderSetState(ts)
visit.DrawPlots()
visit.SaveWindow()
visit_utils.encoding.encode(stillname, "solarforcing_v2_output.%s" % format, input_frame_rate = 3)
# If make_movie is False, just render to the screen
else:
visit.DrawPlots()