pencil.visu.pv_plotter
These are generic requirements for all PyVista plotter tools including
pv_plotter.py, pv_volume_plotter.py and pv_plotter_utils.py.
- pyvista
-> latest version (version >= 0.31.3) otherwise there might be issues with the pyvista.streamlines_from_source() function
imageio-ffmpeg
tqdm
numpy
sklearn — necessary for pv_volume_plotter.py parameter tests.
All of these can be installed by:
`
pip3 install <Library name>
`
All pyvista plotting tools are tested to work with versions: VTK==9.0.3 and pyvista==0.31.3.
Furthermore, in order to save videos, PyVista requires imageio-ffmpeg. Note that
saving only images is faster and should be used instead in combination with e.g.
imagemagick on command line. If using progress_bar parameter, tqdm is needed.
Pyvista plot generation does not work on CSC Puhti without loading the module
mesa-settings.
General
This file defines a routine for generating 3D visualisation from video slices. It is able to generate both images (e.g. png) and videos (mp4/gif). This uses PyVista in order to generate plots in cartesian | spherical | cylindrical coordinates.
User should call the function plot() to generate the visualizations. See documentation of plot() for further usage examples and parameters.
Plot availability for each coordinate system
|-----------------------|———–|-----------|———-| | Scalars | X | X | X | | + surface vectors | X | X | - | | + surface streamlines | X | X | - |
Things to note
STREAMLINES: increasing number of source points, steps in integration or even field itself can have a large effect on the used memory / time that takes to create one frame.
Attributes
Classes
Defines all possible settings and defaults for all plots. Defining |
Functions
|
Create plot from slice data in cartesian | spherical | cylindrical |
Module Contents
- pencil.visu.pv_plotter.XYZPLANE_KEYS = ['xy', 'xy2', 'xz', 'yz']
- pencil.visu.pv_plotter.CONSTANT_SEED
- class pencil.visu.pv_plotter.PlotSettings
Defines all possible settings and defaults for all plots. Defining this as a class has the advantage of keeping all default and parameter settings in one maintainable place and removes the hassle of e.g. using kwargs.
Quick Tutorial
Class
PlotSettings()defines all possible settings in addition to the parameters function plot() takes in. For further information about all the possible parameters, see documentation ofPlotSettings.The class can be initialized in at least three ways:
1. Pass in the parameters: >>> settings = PlotSettings(off_screen=True, preview=False, …)
2. Define a dictionary and pass that in using asterisk notation: >>> params = {
‘off_screen’: True, ‘preview’: False, …
} >>> settings = PlotSettings(**params)
3. Initialize class and change the values in more ‘object-oriented’ way: >>> settings = PlotSettings() >>> settings.off_screen = True >>> settings.preview = False
GENERAL PARAMETERS
- off_screen: bool
Whether plotting should be done on screen or off screen
- preview: bool
Interactive preview, specific slice can be set by islice parameter in plot()
- window_size: tuple
should be multiple of macro_block_size=16 for imageio-ffmpeg
- progress_bar: bool
Enable tqdm progress bar
- videoformat: str
Options: None | ‘mp4’ | ‘gif’
- imageformat: str
Options: None | ‘png’ | ‘jpeg’ | etc., any Pillow compatible imageformat
- framerate: int
Movie framerate. Does not affect gif.
- figdir: str
Path to save images
- moviedir: str
Path to save movies
- bg_color: str or 3 item list
Background color. Either string or 3 tuple in RGB format.
- timestamp: bool
Add timestamp to saved output filename.
PLOT PARAMETERS
- norm: str
Normalization applied. Options: ‘linear’ | ‘log’
- coordinates: str
Options: ‘cartesian’ | ‘spherical’ | ‘cylinder’
- opacities: dict
Opacities per slice. Should be dict with keys ‘xy’, ‘xy2’, ‘yz’ and ‘xz’.
COORDINATE SPECIFIC PARAMETERS
- offset: float
Offset for the bottom slice. Z-coordinate of the bottom mesh is set to -zn / offset, where zn is the number of points in z-direction.
- spherical_xz_pos: float
Options: None | -1 | <angle in radians>. Position for xz slice in spherical coordinates. If None, position inferred from slice data. If -1, slice set to close the gap between meridional slices in one end.
VECTOR PLOT PARAMS
- n_vectors: int
- Depending on chosen vector_method:
method==’every_nth’: Plot only every n_vectors vectors
- method==’random’: Plot a total of n_vectors, source point chosen
randomly
- vector_size: float
Affects the size of plotted vectors.
- vector_method: str
- Options:
‘random’ = random sampled points
‘every_nth’ = plot every nth vector (defined by n_vectors)
- vector_scaling: str
- Scaling of vectors. Options:
None, no scaling applied
2. ‘magnitude’, vectors scaled by their magnitude (to max size defined vector_max) 3. ‘scalars’, vectors scaled based on the scalar data on the surface.
- vector_max: float
Maximum value for vector size. Useful, e.g. if vectors scaled by their magnitude that they’re not arbitrarily large.
- surface_vectors: bool
If True, always one vector component set to zero (depending on which mesh were on). If False, the plotted vectors have also their 3rd component, i.e. not constrained on to the 2D surface.
STREAMLINE PARAMS
- streamlines: bool
Enable streamlines. If False, and vectors are supplied vectors are plotted instead.
- stream_tube_radius: float
Radius for the streamline tubes.
- stream_variable_radius: str
Enable scaling of stream tube radius. Input should be name of the scalar array used for scaling. Available arrays include ‘Magnitude’ and ‘scalars’. If None, streamline tube radius stays constant
Extra: PyVista includes some internal scalar arrays if stream_params has ‘compute_vorticity’=True. This includes e.g. ‘Vorticity’ array. The names of these are the easiest found by modifying __addSurfaceStreamlines function, see output of: print(stream.point_arrays) for available arrays.
- stream_radius_factor: float
Maximal radius of stream tube as a multiple of stream_tube_radius.
- stream_src_points: int or dict
Number of source points given either as an integer (all meshes have same number of src points) or as a dictionary containing keys ‘xy’, ‘xy2’, ‘xz’ and ‘yz’ defining number of source points for each mesh.
- stream_show_source: bool
Show source points as spheres in the plot.
- stream_log_scale: bool
Enables pyvista.add_mesh log_scale, i.e. applies logarithm for the values to be added to the colorbar.
- stream_params: dict
Any parameters pyvista streamlines_from_source() takes in OTHER THAN surface_streamlines and vectors. The following is the Pyvista’s own documentation on the pyvista.streamlines_from_source, see link for documentation after the list:
- integrator_type
The integrator type to be used for streamline generation. The default is Runge-Kutta45. The recognized solvers are: RUNGE_KUTTA2 (2), RUNGE_KUTTA4 (4), and RUNGE_KUTTA45 (45). Options are 2, 4, or 45. Default is 45.
- integration_direction
Specify whether the streamline is integrated in the upstream or downstream directions (or both). Options are ‘both’, ‘backward’, or ‘forward’.
- initial_step_length
Initial step size used for line integration, expressed in length unitsL or cell length units (see step_unit parameter). either the starting size for an adaptive integrator, e.g., RK45, or the constant / fixed size for non-adaptive ones, i.e., RK2 and RK4).
- step_unit
Uniform integration step unit. The valid unit is now limited to only LENGTH_UNIT (‘l’) and CELL_LENGTH_UNIT (‘cl’). Default is CELL_LENGTH_UNIT: ‘cl’.
- min_step_length
Minimum step size used for line integration, expressed in length or cell length units. Only valid for an adaptive integrator RK45.
- max_step_length
aximum step size used for line integration, expressed in length or cell length units. Only valid for an adaptive integrator RK45.
- max_steps
Maximum number of steps for integrating a streamline.
- terminal_speed
Terminal speed value, below which integration is terminated.
- max_error
Maximum error tolerated throughout streamline integration.
- max_time
Specify the maximum length of a streamline expressed in LENGTH_UNIT.
- compute_vorticity
Vorticity computation at streamline points (necessary for generating proper stream-ribbons using the vtkRibbonFilter.
- interpolator_type
Set the type of the velocity field interpolator to locate cells during streamline integration either by points or cells. The cell locator is more robust then the point locator. Options are ‘point’ or ‘cell’ (abbreviations of ‘p’ and ‘c’ are also supported).
- rotation_scale
This can be used to scale the rate with which the streamribbons twist. The default is 1
See https://docs.pyvista.org/core/filters.html?highlight=streamlines_from_source#pyvista.DataSetFilters.streamlines_from_source for more details on the parameters.
Note that if stream_params is None the following defaults are set: >>> self.stream_params = {
‘max_steps’: 1000, ‘max_time’: 1e60, ‘terminal_speed’: 1e-60, ‘integration_direction’: ‘both’, ‘compute_vorticity’: False, ‘integrator_type’: 45,
}
RANDOM SAMPLING PARAMS
- set_seed_1: bool
For debugging, always sets random seed to 1, thus all sampled points are the same. Makes comparing streamlines easier for debugging
- constant_seed: bool
Sets random seed once in the beginning and resets the random generator always with this seed. This has the consequence of randomizing initial points, keeping them constant, e.g. throught the movie. Makes streamlines jump less around the meshes.
CAMERA PARAMS
- camera_centre: tuple of floats
Coordinates for camera centre in form (x, y, z).
- focal_point: tuple of floats
Focal point for the camera in form (x, y, z).
AXES PARAMS
- show_axes: bool
Show axes or not.
- axes_labels: tuple of str
Labels for the axes. Should be tuple of length 3 containing strings.
- axes_font: int
Font for the axes labels
COLORBAR PROPERTIES: field specific (vectors | streamlines)
- show_field_sbar: bool
Show scalarbar for vectors / streamlines
- field_cmap: str
Matplotlib compatible colormap for vectors / streamlines
- field_sbar_title: str
Title for fields scalarbar.
pos_x and pos_y are given as a float between 0 and 1 (percentage). That is it defines the distance from leftmost edge (pos_x) and bottom most edge (pos_y). E.g. pos_x = 0 would mean colorbar is set at the very leftmost edge. NOTE! if both None, colorbars set automatically, also works for multiple colorbars set nicely next to each other.
- field_sbar_pos_x: float
If None set automatically. Else float in range [0,1]. Note, 0.03 is pretty good value (fairly close to left edge)
- field_sbar_pos_y: float
None or float between [0,1]. None works well
COLORBAR PROPERTIES: scalar specific
- show_scalar_sbar: bool
Show scalarbar for scalars
- scalar_cmap: str
Matplotlib compatible colormap for scalars.
- scalar_sbar_title: str
Title for scalar scalarbar.
- scalar_sbar_pos_x: float
None or float between [0,1]. Note, 0.88 is pretty good value (enough close to right edge). See notes above for detailed explanation of pos_x
- scalar_sbar_pos_y: float
None or float between [0,1]. Note, None works well. See notes above for detailed explanation of pos_y
COLORBAR PROPERTIES: Generic properties
Following parameters apply both to field and scalar colorbars.
- cbar_width: float
Width as a percentage, between 0 and 1
- cbar_height: float
Height as a percentage, between 0 and 1
- cbar_title_font: int
Title font size for scalarbar
- cbar_label_font: int
Label font size for scalarbar
- n_colors: int
Number of colors for the scalarbar.
- _sbar_args: dict
INTERNAL VALUE. SHOULD NOT BE USED.
TITLE ANNOTATIONS
- title_position: str
Options: ‘lower_left’, ‘lower_right’, ‘upper_left’, ‘upper_right’, ‘lower_edge’, ‘upper_edge’, ‘right_edge’, and ‘left_edge’.
- title_font: int
Font size for the title.
- str_unit: str
Unit added behind the timestamp in the title. I.e. title is form ‘<current time step><str_unit>’
- tscale: float
Multiplicative scaling for the timestamp in title.
- time_precision: int
Number of decimals shown for the timestamp.
- pencil.visu.pv_plotter.plot(slice_obj=None, datadir='./data', precision='f', fields=['uu1'], xyzplane={'xy2': 'xy2', 'xy': 'xy', 'yz': 'yz', 'xz': 'xz'}, vectors=None, tstart=0.0, tend=1e+38, islice=-1, istart=None, iend=None, color_range=None, color_levels=None, unit='unit_velocity', rescale=1.0, par=list(), debug=True, settings=PlotSettings()) None
Create plot from slice data in cartesian | spherical | cylindrical coordinates and saves the output as images and / or videos. Creates plots for times [tstart, tend] of all the fields specified in fields argument. Internally calls __plot_field() to handle plotting of a given field over all time instants. By default this function creates images off screen without creating interactive plot window. If plotting done on screen (i.e. off_screen=False) and creating a video, one can see the video live and the video angle can be rotated, also affecting the output video.
In case of fine tuning the plot parameters, e.g. camera position / focal point, one can turn preview on (in settings) to see an interactive plot window that can be rotated around and outputs the camera parameters on both command line and the plot window.
- Parameters:
slice_obj (pencil.read.allslices.SliceSeries, optional) – Pencil slice data, if supplied no slice data is read. If None, slice data is automatically read from datadir. Default: None.
datadir (str, optional) – Directory of the data. Default: ‘./data’.
precision (str, optional) – Precision for the data read, parameter e.g. pencil.read.slices() takes in. Can be ‘half’, ‘f’ or ‘d’. Default: ‘f’.
fields (list of strings, optional) – Fields that are plotted. Default: [‘uu1’,].
xyzplane (dictionary, optional) – Dictionary having allowed keys defined by XYZPLANE_KEYS. Values should be the matching data that is plotted on each of these surfaces. See “Coordinate systems” below.
vectors (list, optional) – List of 3 strings defining the vector components of the vector field. This is used to create streamlines / vectors.
tstart (float, optional) – Start time instant. See parameter islice for more details. Default: 0.
tend (float, optional) – End time instant. See parameter islice for more details. Default: 1e38
islice (int, optional) – Sequential integer number of a slice in given period (starting from 0). If set to -1, generates all slices in given period [tstart, tend]. Else generates only visualisations of the given slice number islice. Default: -1.
istart (int, optional) – First index to start plotting from. This index corresponds to time instant slice_obj.t[istart]. istart is used if it is not None, otherwise tstart is used.
iend (int, optional) – Similar to istart, end time index corresponding to time slice_obj.t[iend]
color_range (list of 2, optional) – If supplied, list containing [cmin,cmax] for the colorbar.
color_levels (string, optional) – If set to ‘common’, then all times and fields have same colorbar min and max values. Default: None.
unit (string, optional) – Unit (string) appended to the end of the timestamp in the title.
rescale (int, optional) – TODO!
par (list, optional) – TODO!
debug (boolean, optional) – Enable debugging prints. Default: False.
**settings (optional) – Dictionary of possible settings for the plot. See docstring at the start of this file for an ready dictionary input of all possible parameters settings could take in.
systems (Coordinate)
------------------
['xy' (Allowed keys for xyzplane are defined by XYZPLANE_KEYS =)
'xy2'
'xz'
'yz'].
system (In case of each coordinate)
to (these surfaces correspond)
Cartesian (-) –
xy = bottom
xy2 = top
xz = right vertical slice
yz = left verical slice
Spherical (-) –
xy = r-theta slice, 1st meridional slice
xy2 = r-theta slice, 2nd meridional slice
xz = r-phi slice, “plane slice” between meridionals and yz
yz = theta-phi slice, spherical surface at the back (or part of it)
Cylinder (-) –
xy = r-theta slice, bottom of the cylinder (circle)
xy2 = r-theta slice 2, top of the cylinder (circle)
xz = r-z slice, “radial cut”, rectangle between top/bottom
yz = theta-z slice, shell of the cylinder (or part of it)
Examples
Minimal usage example, this saves by default ‘png’ images at all timesteps of field ‘uu1’ to figure directory ./images (creating the directory if it does not exist). Debug should be left on so one can see that the script runs properly. By default this creates a cartesian plot (i.e. box plot).
>>> from pencil.visu.pv_plotter import plot, PlotSettings >>> plot(debug=True)
This plotter uses a settings object (dataclass) PlotSettings that contains all possible extra settings that can be varied. See documentation on PlotSettings for further information on all of the parameters. This can be used in the following way:
>>> settings = { 'imageformat': None, 'videoformat': 'mp4', 'coordinates': 'cartesian' 'cbar_title': 'TITLE', 'n_colors': 100, 'camera_centre': (-170, -140, 125), 'focal_point': (30, 30, 16), 'offset': 2.5 } >>> settings = PlotSettings(**settings) >>> plot(debug=True settings=settings)
Furthermore, 2D slices to be plotted can be modified by passing in xyzplane parameter
>>> xyzplane = {'xy2': 'xy2','xy': 'xy', 'xz': 'xz', 'yz': 'yz'}
where the string values represent the slices to be plotted on the meshes (see “Coordinate systems” for what which mesh each key corresponds given coordinate system). These values should be found in slices.__dict__.keys().
Notes
NOTE! The default camera angle is most likely horrible and may not even show
the data at all. This should be manually modified and e.g. easily found using preview=True that shows an interactive plot window that can be rotated around and print out the camera parameters at the same time. - NOTE! On CSC computers module ‘mesa-settings’ needs to be loaded (works at least on Puhti).