Examples

Hello World

A simple “Hello, World!” example that does the following:

  1. enables extremely verbose logging
  2. starts the Tecplot 360 EX engine
  3. add text to the active frame
  4. exports the frame to an image file
  5. releases the Tecplot 360 EX License
_images/hello_world.png
import tecplot

frame = tecplot.active_frame()
frame.add_text('Hello, World!', position=(36, 50), size=34)
tecplot.export.save_png('hello_world.png', 600)

Loading Layouts

Layouts can be loaded with the tecplot.load_layout() method. This will accept both lay and lpk (packaged) files. The exported image interprets the image type by the extension you give it. See tecplot.export.save_png() for more details.

_images/jet_surface.png
import logging
import os
import sys

logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

import tecplot

examples_dir = tecplot.session.tecplot_examples_directory()
infile = os.path.join(examples_dir, '3D', 'JetSurface.lay')

tecplot.load_layout(infile)
tecplot.export.save_jpeg('jet_surface.jpeg', 600)

Exception Handling

It is the policy of the PyTecplot Python module to raise exceptions on any failure. It is the user’s job to catch them or otherwise prevent them by ensuring the Tecplot Engine is properly setup to the task you ask of it. Aside from exceptions raised by the underlying Python core libraries, PyTecplot may raise a subclass of TecplotError, the most common being TecplotRuntimeError.

_images/spaceship.png
import logging
import os

logging.basicConfig(level=logging.DEBUG)

import tecplot
from tecplot.exception import *


# Calling tecplot.session.acquire_license() is optional.
# If you do not call it, it will be called automatically for you
# the first time you call any |PyTecplot| API.
#
# acquire_license() may also be called manually. It will raise an exception
# if Tecplot cannot be initialized. The most common reason that
# Tecplot cannot be initialized is if a valid license is not found.
# If you call start yourself, you can catch and recover from the
# exception.
#
# Note that calling tecplot.session.stop() will release the license acquired
# when calling tecplot.session.|PyTecplot|().
#
# Also note that once tecplot.session.stop() is called, |Tecplot Engine|
# cannot be restarted again during the current python session.
#
try:
    tecplot.session.acquire_license()
    logging.info('License acquired, Tecplot Engine started.')
except TecplotLicenseError:
    logging.exception('Missing or invalid license:')
except TecplotError:
    logging.exception('Could not initialize pytecplot')
    exit(1)

examples_dir = tecplot.session.tecplot_examples_directory()
infile = os.path.join(examples_dir, '3D', 'spaceship.lpk')
outfile = 'spaceship.png'

try:
    logging.info('Opening layout file: ' + infile)
    tecplot.load_layout(infile)

    logging.info('Exporting Image: ' + outfile)
    tecplot.export.save_png(outfile, 600)

    logging.info('Finished, no errors')

except IOError:
    logging.debug("I/O Error: Check disk space and permissions")
except TecplotSystemError:
    logging.exception('Failed to export image: ' + outfile)
finally:
    # tecplot.session.stop() may be called manually to shut down Tecplot and release
    # the license.
    # If tecplot.session.stop() is not called manually it will be called automatically
    # when the script exits.
    tecplot.session.stop()

logging.info('Done')

Extracting Slices

This script produces two images: a 3D view of the wing and a simplified pressure coefficient plot half-way down the wing:

_images/wing.png
_images/wing_pressure_coefficient.png
import os
import sys
import logging

logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

import tecplot

examples_dir = tecplot.session.tecplot_examples_directory()
datafile = os.path.join(examples_dir, 'OneraM6wing', 'OneraM6_SU2_RANS.plt')
dataset = tecplot.data.load_tecplot(datafile)

frame = tecplot.active_frame()
frame.plot_type = tecplot.constant.PlotType.Cartesian3D
frame.plot().show_contour = True

# export image of wing
tecplot.export.save_png('wing.png', 600)

# extract an arbitrary slice from the surface data on the wing
extracted_slice = tecplot.data.extract.extract_slice(
    origin=(0, 0.25, 0),
    normal=(0, 1, 0),
    slicesource=tecplot.constant.SliceSource.SurfaceZones,
    dataset=dataset)

extracted_slice.name = 'Quarter-chord C_p'

# get x from slice
extracted_x = extracted_slice.variable('x')

# copy of data as a numpy array
x = extracted_x.as_numpy_array()

# normalize x
xc = (x - x.min()) / (x.max() - x.min())
extracted_x[:] = xc

# switch plot type in current frame
frame.plot_type = tecplot.constant.PlotType.XYLine
plot = frame.plot()

# clear plot
plot.delete_linemaps()

# create line plot from extracted zone data
cp_linemap = plot.add_linemap(
    name=extracted_slice.name,
    zone=extracted_slice,
    x=dataset.variable('x'),
    y=dataset.variable('Pressure_Coefficient'))

# set style of linemap plot
cp_linemap.line.color = tecplot.constant.Color.Blue
cp_linemap.line.line_thickness = 0.8
cp_linemap.y_axis.reverse = True

# update axes limits to show data
plot.view.fit()

# export image of pressure coefficient as a function of x/c
tecplot.export.save_png('wing_pressure_coefficient.png', 600)

Numpy Integration

Note

Numpy, SciPy Required

This example requires both numpy and scipy installed. SciPy, in turn, requires a conforming linear algebra system such as OpenBLAS, LAPACK, ATLAS or MKL. It is recommended to use your operating system’s package manager to do this. Windows users and/or users that do not have root access to their machines might consider using Anaconda to setup a virtual environment where they can install python, numpy, scipy and all of its dependencies.

The spherical harmonic (n,m) = (5,4) is calculated at unit radius. The magnitude is then used to create a 3D shape. The plot-style is modified and the following image is exported and the layout is saved in “packaged format.” The methods used in this example should be considered very low-level and in a “pre-alpha”/early stage in development:

_images/spherical_harmonic_4_5.png
import logging as log
import numpy as np
from numpy import abs, pi, cos, sin
from scipy import special

log.basicConfig(level=log.INFO)

import tecplot as tp
from tecplot.session import set_style
from tecplot.constant import ColorMapDistribution

shape = (300, 300)


log.info('creating spherical harmonic data')
r = 0.3
phi = np.linspace(0, pi, shape[0])
theta = np.linspace(0, 2*pi, shape[1])

pphi, ttheta = np.meshgrid(phi, theta)

xx = r * sin(pphi) * cos(ttheta)
yy = r * sin(pphi) * sin(ttheta)
zz = r * cos(pphi)

n = 5
m = 4

ss = special.sph_harm(m, n, ttheta, pphi).real
ss /= ss.max()

log.info('creating tecplot dataset')
ds = tp.active_frame().dataset

ds.add_variable('x')
ds.add_variable('y')
ds.add_variable('z')
ds.add_variable('s')

sphere_zone = ds.add_ordered_zone(
    'SphericalHarmonic({}, {}) Sphere'.format(m, n),
    shape)

sphere_zone.variable('x')[:] = xx.ravel()
sphere_zone.variable('y')[:] = yy.ravel()
sphere_zone.variable('z')[:] = zz.ravel()
sphere_zone.variable('s')[:] = ss.ravel()

tp.session.zones_added(sphere_zone)

log.info('creating shaped zone')
shaped_zone = ds.add_ordered_zone(
    'SphericalHarmonic({}, {}) Shaped'.format(m, n),
    shape)

shaped_zone.variable('x')[:] = (abs(ss)*xx).ravel()
shaped_zone.variable('y')[:] = (abs(ss)*yy).ravel()
shaped_zone.variable('z')[:] = (abs(ss)*zz).ravel()
shaped_zone.variable('s')[:] = ss.ravel()

log.info('state changed: zones added')
tp.session.zones_added(shaped_zone)

log.info('setting plot type to Cart3D')
tp.active_frame().plot_type = tp.constant.PlotType.Cartesian3D
plot = tp.active_frame().plot()

'''
The lines below are equivalent to the macro commands.

Notice that PyTecplot indexes universally from zero where the
macro indexes from one.

$!FIELDLAYERS SHOWCONTOUR = YES
$!FIELDLAYERS USETRANSLUCENCY = YES
$!FIELDMAP [1]  EFFECTS { SURFACETRANSLUCENCY = 70 }
$!FIELDMAP [2]  EFFECTS { SURFACETRANSLUCENCY = 30 }
$!GLOBALCONTOUR 1  COLORMAPFILTER { COLORMAPDISTRIBUTION = CONTINUOUS }
$!GLOBALCONTOUR 1  COLORMAPNAME = 'Sequential - Yellow/Green/Blue'
'''
plot.show_contour = True
plot.show_translucency = True
plot.fieldmap(sphere_zone).effects.surface_translucency = 70
plot.fieldmap(shaped_zone).effects.surface_translucency = 30
plot.contour(0).colormap_filter.distribution = ColorMapDistribution.Continuous
plot.contour(0).colormap_name = 'Sequential - Yellow/Green/Blue'

filename = 'spherical_harmonic_{}_{}'.format(m, n)

log.info('saving image')
tp.export.save_png(filename + '.png', 600)

log.info('saving packaged layout file')
tp.save_layout(filename + '.lpk', include_data=True)

log.info('releasing license')

Execute Equation

This example illustrates altering data through equations in one or more zones. For complete information on the Tecplot Engine data alter syntax, see Chapter 21, Data Operations, in the Tecplot 360 User’s Manual.
import logging
import os
import sys

logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

import tecplot
from tecplot.data.operate import execute_equation
from tecplot import active_frame

examples_dir = tecplot.session.tecplot_examples_directory()
infile = os.path.join(examples_dir, '3D', 'JetSurface.lay')
outfile = 'jet_surface.png'
tecplot.load_layout(infile)
current_dataset = active_frame().dataset  # type: tecplot.data.dataset.Dataset

# alter variable 'Nj' for the the two wing zones in the dataset
# In this simple example, just multiply it by 10.
execute_equation('{Nj}={Nj}*10', zones=[current_dataset.zone('right wing'),
                                        current_dataset.zone('left wing')])

# The contour color of the wings in the exported image will now be
# red, since we have altered the 'Nj' variable by multiplying it by 10.
tecplot.export.save_png(outfile, 600)

Line Plots

This example shows how to set the style for a plot of three lines. The y-axis label and legend labels are changed and the axes are adjusted to fit the data.
_images/linemap.png
from os import path
import tecplot as tp
from tecplot.constant import PlotType, Color, LinePattern

# load data from examples directory
examples_dir = tp.session.tecplot_examples_directory()
infile = path.join(examples_dir, 'XY', 'rainfall.plt')
dataset = tp.data.load_tecplot(infile)

# get handle to the active frame and set plot type to XY Line
frame = tp.active_frame()
frame.plot_type = PlotType.XYLine
plot = frame.plot()

# We will set the name, color and a few other properties
# for the first three linemaps in the dataset.
names = ['Seattle', 'Dallas', 'Miami']
colors = [Color.Blue, Color.DeepRed, Color.Khaki]

# loop over the linemaps, setting style for each
for lmap,name,color in zip(plot.linemaps(),names,colors):
    lmap.show = True
    lmap.name = name # This will be used in the legend

    # Changing some line attributes
    line = lmap.line
    line.color = color
    line.line_thickness = 1
    line.line_pattern = LinePattern.LongDash
    line.pattern_length = 2

# Set the y-axis label
plot.axes.y_axis(0).title.text = 'Rainfall'

# Turn on legend
plot.legend.show = True

# Adjust the axes limits to show all the data
plot.view.fit()

# save image to file
tp.export.save_png('linemap.png', 600)