Spherical Plotting utility

Overview

This module provides tools for creating and viewing spherical plots.

The spherical plotting tool, using Mayavi, requires two sets of data in order to create the spherical plot: the vertex locations in (x,y,z) and the spatial relationship between the vertices, i.e. triangulation of nearest neighbours. This spatial relationship is required to create surface elements between the vertices. If the spatial relationship is not known, the data is merely a cloud of points, with no surface content.

The easiest way to create the spatial relationships between the vertices was to use a complex hull polygon model of an object. The polygon or wireframe model has the requires vertices and spatial relationships.

In the original application of this tool, a series of spheres were created using MeshLab. The essential property of these spheres was that the vertices on the surface of the spheres were spaced equidistant over the surface, i.e. an optimal spatial sampling distribution. The files were exported as OFF files, and should be in the pyradi data/plotspherical directory. There are 6 possible input files, each with different number of samples on the unit sphere: 12, 42, 162, 642, 2562 or 10242.

Any object, with the required vertices and spatial relationships can be used. it does not have to be equi-sampled spheres.

Note that the spherical plot has no way to discriminate between negative values and a pi phase shift: there is confusion between sign and direction. This is inherent in the conversion between cartesian and spherical coordinates. The user has to make provision for this, possibly by plotting only negative or only positive values.

The data must be in the OFF wireframe format.

There are two possible trajectory file types:
  • ‘Rotate’ Stationary sensor and object with the target rotating. In this case the trajectory file specifies the target trajectory.
  • ‘Orbit’ Stationary object with orbiting sensor. In this case the trajectory file specifies the sensor trajectory.

The sphere data available in pyradi/data/plotspherical are:

Filename Resolution Number Number
. (degrees) points triangles
sphere_0_12 63.4 12 20
sphere_1_42 33.9 42 80
sphere_2_162 17.2 162 320
sphere_3_642 8.6 642 1280
sphere_4_2562 4.32 2562 5120
sphere_5_10242 2.16 10242 20480
sphere_6_40962 1.08 40962 81920
sphere_7_163842 0.54 163842 327680
The workflow is as follows:
  1. Use writeOSSIMTrajOFFFile (or your own equivalent) to calculate the appropriate trajectory file. At the same time, there are two additional files created (vertices and triangles) - keep these safe.
  2. Create your data set (e.g. run simulation) using the trajectory file. Collect the simulation data in a format for plotting.
  3. Use the simulation data, together with the triangles and vertices file, to plot the data. The triangles and vertices are require to set up the plotting environment, consider this the three-dimensional ‘grid’, while the simulation data provides the data to be plotted in this grid.

This tool was originally developed to create trajectory files for the Denel/CSIR OSSIM simulation. The code was restructured for greater universal application, but the final example is still an OSSIM case.

See the __main__ function for examples of use.

Module functions

pyradi.ryplotspherical.readOffFile(filename)

Reads an OFF file and returns the vertices and triangles in numpy arrays.

The OFF file is read and the data captured in the array structures. This is a fairly trivial reading task.

Args:
filename (string): name of the OFF file
Returns:
vertices(numpy.array([])): array of vertices as [x y z]
triangles(numpy.array([])): array of triangles as []
Raises:
No exception is raised.
pyradi.ryplotspherical.getRotateFromOffFile(filename, xPos, yPos, zPos)

Reads an OFF file and returns object attitude and position.

Calculate the pitch and yaw angles to point the object’s X-axis towards the OFF file vertex directions.

Euler order is yaw-pitch-roll, with roll equal to zero. Yaw is defined in xy plane. Pitch is defined in xz plane. Roll is defined in yz plane.

The object is assumed to stationary at the position (xPos, yPos, zPos), the position arrays are the same length as the attitude angle arrays, but all values in each individual array are all the same.

Args:
filename (string): OFF file filename
xPos (double): object position on x axis
yPos (double): object position on y axis
zPos (double): object position on z axis
Returns:
x(numpy.array()): array of x object location values
y(numpy.array()): array of y object location values
z(numpy.array()): array of z object location values
roll(numpy.array()): array of object location roll values
pitch(numpy.array()): array of object location pitch values
yaw(numpy.array()): array of object location yaw values
vertices(numpy.array([])): array of vertices as [x y z]
triangles(numpy.array([])): array of triangles as []
Raises:
No exception is raised.
pyradi.ryplotspherical.getOrbitFromOffFile(filename, xTargPos, yTargPos, zTargPos, distance)

Reads an OFF file and returns sensor attitude and position.

Calculate the sensor attitude and position such that the sensor always look at the object located at ( xTargPos, yTargPos, zTargPos), at a constant distance.

Euler order is yaw-pitch-roll, with roll equal to zero. Yaw is defined in xy plane. Pitch is defined in xz plane. Roll is defined in yz plane.

The object is assumed to stationary at the position (xTargPos, yTargPos, zTargPos).

Args:
filename (string): OFF file filename
xTargPos (double): x target object position (fixed)
yTargPos (double): y target object position (fixed)
zTargPos (double): z target object position (fixed)
distance (double): range at which sensor orbits the target
Returns:
x(numpy.array()): array of x sensor position values
y(numpy.array()): array of y sensor position values
z(numpy.array()): array of z sensor position values
roll(numpy.array()): array of sensor roll values
pitch(numpy.array()): array of sensor pitch values
yaw(numpy.array()): array of sensor yaw values
vertices(numpy.array([])): array of vertices as [x y z]
triangles(numpy.array([])): array of triangles as []
Raises:
No exception is raised.
pyradi.ryplotspherical.writeOSSIMTrajOFFFile(filename, trajType, distance, xTargPos, yTargPos, zTargPos, xVel, yVel, zVel, engine, deltaTime)

Reads OFF file and create OSSIM trajectory files for rotating object or orbiting sensor.

This function writes a file in the custom OSSIM trajectory file format. Use this function as an example on how to use the ryplotspherical functionality in your application.

Two different types of trajectory files are created:
  1. trajType = ‘Rotate’ Calculate attitude (pitch and yaw angles only, roll is zero) to orientate an object’s x-axis along the vertices in the OFF file. The location of the object is fixed at (xTargPos,yTargPos,zTargPos).
  2. trajType = ‘Orbit’ Calculate location and attitude (pitch and yaw angles only, roll is zero) of an orbiting sensor looking a a fixed location (xTargPos, TargPos, zTargPos) from a given distance.

The velocity and engine settings are constant for all views at the values specified.

The deltaTime parameter is used to define the time increment to be used in the trajectory file.

Two additional files are also written to assist with the subsequent viewing.

  1. The vertex file contains the normalised direction vectors between the object and observer. Depending on the trajectory type (see above), the sensor and object switch locations for these vectors. These vectors are the directions of sampled intensity values.
  2. The triangles file defines triangles that provides the spatial linking between adjacent vectors, used when plotting the data. We plot the complex hull comprising these triangles, with vertices along the direction vectors, with length given by the simulated data set.

OSSIM Users: For examples of how to use these trajectory files, see test points tp01l (that is lowercase L) and tp01m. The scenario files are present in the the appropriate test point directory (l and m) and the plotting routines are in the tp01 utils directory.

Args:
filename (string): OFF file filename
trajType (string): type of trajectory: ‘Rotate’ or ‘Orbit’
distance (double): distance from sensor to object
xTargPos (double): object x position.
yTargPos (double): object y position.
zTargPos (double): object z position.
xVel (double): velocity in x direction
yVel (double): velocity in y direction
zVel (double): velocity in z direction
engine (double): engine settiing
deltaTime (double): sampling time increment in output file
Returns:
writes a trajectory file
writes a triangles file
writes a vertices file
Raises:
No exception is raised.
pyradi.ryplotspherical.writeOSSIMTrajElevAzim(numSamplesAz, filename, trajType, distance, xTargPos, yTargPos, zTargPos, xVel, yVel, zVel, engine, deltaTime)

Create OSSIM trajectory files for rotating object or orbiting sensor for constant increments in azimuth and elevation (yaw and pitch).

This function writes a file in the custom OSSIM trajectory file format. Use this function as an example on how to use the ryplotspherical functionality in your application.

Two different types of trajectory files are created:
  1. trajType = ‘Rotate’ Calculate attitude (pitch and yaw angles only, roll is zero) to orientate an object’s x-axis along the elevation and azimuth vectors. The location of the object is fixed at (xTargPos,yTargPos,zTargPos).
  2. trajType = ‘Orbit’ Calculate location and attitude (pitch and yaw angles only, roll is zero) of an orbiting sensor looking a a fixed location (xTargPos, TargPos, zTargPos) from a given distance along the elevation and azimuth vectors.

The velocity and engine settings are constant for all views at the values specified.

The deltaTime parameter is used to define the time increment to be used in the trajectory file.

Two additional files are also written to assist with the subsequent viewing.

  1. The azimuth file contains the sample values around the equator. The value ranges from zero to two*pi
  2. The elevation file contains the sample values from North pole to South pole. The value ranges from -pi to +pi
Args:
numSamplesAz (int): The number of samples along the equator
filename (string): output file filename
trajType (string): type of trajectory: ‘Rotate’ or ‘Orbit’
distance (double): distance from sensor to object
xTargPos (double): object x position.
yTargPos (double): object y position.
zTargPos (double): object z position.
xVel (double): velocity in x direction
yVel (double): velocity in y direction
zVel (double): velocity in z direction
engine (double): engine settiing
deltaTime (double): sampling time increment in output file
Returns:
writes a trajectory file
writes a azimuth, elevation file
Raises:
No exception is raised.
pyradi.ryplotspherical.getOrbitFromElevAzim(azimuth, elevation, xTargPos, yTargPos, zTargPos, distance)

Reads an OFF file and returns sensor attitude and position.

Calculate the sensor attitude and position such that the sensor always look at the object located at ( xTargPos, yTargPos, zTargPos), at a constant distance.

Euler order is yaw-pitch-roll, with roll equal to zero. Yaw is defined in xy plane. Pitch is defined in xz plane. Roll is defined in yz plane.

The object is assumed to stationary at the position (xTargPos, yTargPos, zTargPos).

Args:
azimuth (numpy.array(N,)): azimuth values
elevation (numpy.array(N,)): azimuth values
filename (string): OFF file filename
xTargPos (double): x target object position (fixed)
yTargPos (double): y target object position (fixed)
zTargPos (double): z target object position (fixed)
distance (double): range at which sensor orbits the target
Returns:
x(numpy.array()): array of x sensor position values
y(numpy.array()): array of y sensor position values
z(numpy.array()): array of z sensor position values
roll(numpy.array()): array of sensor roll values
pitch(numpy.array()): array of sensor pitch values
yaw(numpy.array()): array of sensor yaw values
azel(numpy.array()): array of azimuth,elevation values for each sample
Raises:
No exception is raised.
pyradi.ryplotspherical.getRotateFromElevAzim(azimuth, elevation, xPos, yPos, zPos)

Reads an OFF file and returns object attitude and position.

Calculate the pitch and yaw angles to point the object’s X-axis towards the OFF file vertex directions.

Euler order is yaw-pitch-roll, with roll equal to zero. Yaw is defined in xy plane. Pitch is defined in xz plane. Roll is defined in yz plane.

The object is assumed to stationary at the position (xPos, yPos, zPos), the position arrays are the same length as the attitude angle arrays, but all values in each individual array are all the same.

Args:
azimuth (numpy.array(N,)): azimuth values
elevation (numpy.array(N,)): azimuth values
xPos (double): object position on x axis
yPos (double): object position on y axis
zPos (double): object position on z axis
Returns:
x(numpy.array()): array of x object location values
y(numpy.array()): array of y object location values
z(numpy.array()): array of z object location values
roll(numpy.array()): array of object location roll values
pitch(numpy.array()): array of object location pitch values
yaw(numpy.array()): array of object location yaw values
azel(numpy.array()): array of azimuth,elevation values for each sample
Raises:
No exception is raised.
pyradi.ryplotspherical.plotSpherical(figure, dataset, vertices, triangles, ptitle=u'', tsize=0.4, theight=1)

Plot the spherical data given a data set, triangle set and vertex set.

The vertex set defines the direction cosines of the individual samples. The triangle set defines how the surfrace must be structured between the samples. The data set defines, for each direction cosine, the length of the vector.

Args:
figure(int): mlab figure number
dataset(numpy.array(double)): array of data set values
vertices(numpy.array([])): array of direction cosine vertices as [x y z]
triangles(numpy.array([])): array of triangles as []
ptitle(string): title or header for this display
tsize(double): title width in in normalised figure width
theight(double): title top vertical location in normalised figure height
Returns:
provides an mlab figure.
Raises:
No exception is raised.
pyradi.ryplotspherical.plotOSSIMSpherical(basefigure, nColours, plottitle, datafile, vertexfile, trianglefile)

Plot the spherical data given a data set, triangle set and vertex set.

The vertex set defines the direction cosines of the individual samples. The triangle set defines how the surfrace must be structured between the samples. The data set defines, for each direction cosine, the length of the vector.

There is no means to discriminate between negative and pi phase shift. In this function we plot colour ratio values initially in absolute form, then only positive and then only negative values. In between these two shells the values are going through zero.

Args:
basefigure (int): value where figure count must start
nColours ([int]): selection of colours to display
plottitle (string): plot title or header
datafile (string): dataset file filename
vertexfile (string): vertex file filename
trianglefile (string): triangles file filename
Returns:
provides an mlab figure.
Raises:
No exception is raised.
pyradi.ryplotspherical.sphericalPlotElevAzim(figure, azimuth, elevation, value, ptitle=None, colormap=u'Spectral', doWireFrame=False, line_width=0.2)

Plot spherical data (azimuth, elevation and value) given in spherical format

This function assumes that the polar data is defined in terms of elevation angle with zero at the equator and azimuth measured around the equator, from 0 to 2pi. All angles are in degrees.

All axes, x, y, and z are scaled with the magnitude of value in the (azim, elev) direction.

The colour on the surface represents the value at the given azim/elev location.

Args:
figure (int): mlab figure number
azimuth (numpy 1D array): vector of values
elevation (numpy 1D array): vector of values
value (numpy 2D array): array with values corresponding with azim/elevation
ptitle (string): plot title
colormap (string): defines the colour map to be used
doWireFrame (bool): switches fireframe on or off
line_width (double): wireframe line width
Returns:
provides an mlab figure.
Raises:
No exception is raised.
pyradi.ryplotspherical.polarPlotElevAzim(figure, azimuth, elevation, value, ptitle=None, colormap=u'Spectral', doWireFrame=False, line_width=0.2)

Plot spherical data (azimuth, elevation and value) given in polar format.

This function assumes that the polar data is defined in terms of elevation angle with zero at the equator and azimuth measured around the equator, from 0 to 2pi. All angles are in degrees.

The x and y axes are scaled with the maximum magnitude of value. The z axis is scaled with the actual magnitude of value in the (azim, elev) direction.

The colour on the surface represents the value at the given azim/elev location.

Args:
figure (int): mlab figure number
azimuth (numpy 1D array): vector of values
elevation (numpy 1D array): vector of values
value (numpy 2D array): array with values corresponding with azim/elevation
ptitle (string): plot title
colormap (string): defines the colour map to be used
doWireFrame (bool): switches fireframe on or off
line_width (double): wireframe line width
Returns:
provides an mlab figure.
Raises:
No exception is raised.
pyradi.ryplotspherical.globePlotElevAzim(figure, azimuth, elevation, value, ptitle=None, colormap=u'Spectral', doWireFrame=False, line_width=0.2)

Plot spherical data on a sphere.

This function assumes that the polar data is defined in terms of elevation angle with zero at the equator and azimuth measured around the equator, from 0 to 2pi. All angles are in degrees.

The x, y, and z values defines vertices on a sphere. The colour on the sphere represents the value at the given azim/elev location.

Args:
figure (int): mlab figure number
azimuth (numpy 1D array): vector of values
elevation (numpy 1D array): vector of values
value (numpy 2D array): array with values corresponding with azim/elevation
ptitle (string): plot title
colormap (string): defines the colour map to be used
doWireFrame (bool): switches fireframe on or off
line_width (double): wireframe line width
Returns:
provides an mlab figure.
Raises:
No exception is raised.

Table Of Contents

Previous topic

Plotting utility

Next topic

Utility Functions

This Page