from builtins import str, super
from collections.abc import Iterable
from ..constant import *
from ..exception import *
from .. import session, tecutil
from ..tecutil import sv
@tecutil.lock_attributes
class Symbol(object):
def __init__(self, parent, svarg=sv.SYMBOLSHAPE):
self.parent = parent
self._sv = [svarg]
def _get_style(self, rettype, *svargs):
return self.parent._get_style(rettype, *(self._sv + list(svargs)))
def _set_style(self, value, *svargs):
self.parent._set_style(value, *(self._sv + list(svargs)))
@property
def _symbol_type(self):
_stype = {
True: SymbolType.Text,
False: SymbolType.Geometry}
isascii = self._get_style(bool, sv.ISASCII)
if isinstance(isascii, Iterable):
return tuple([_stype[i] for i in isascii])
else:
return _stype[isascii]
@_symbol_type.setter
def _symbol_type(self, value):
value = SymbolType(value)
if value is SymbolType.Text:
self._set_style(True, sv.ISASCII)
else:
self._set_style(False, sv.ISASCII)
[docs]
class TextSymbol(Symbol):
"""Text character for linemap symbols.
Only a single character can be used.
.. code-block:: python
:emphasize-lines: 23,28
from os import path
import tecplot as tp
from tecplot.constant import PlotType, Color, SymbolType, FillMode
examples_dir = tp.session.tecplot_examples_directory()
infile = path.join(examples_dir, 'SimpleData', 'Rainfall.dat')
dataset = tp.data.load_tecplot(infile)
frame = tp.active_frame()
frame.plot_type = PlotType.XYLine
plot = frame.plot()
plot.show_symbols = True
cols = [Color.DeepRed, Color.Blue, Color.Fern]
chars = ['S','D','M']
lmaps = plot.linemaps()
lmaps.show = True
lmaps.symbols.show = True
lmaps.symbols.size = 2.5
lmaps.symbols.color = Color.White
lmaps.symbols.fill_mode = FillMode.UseSpecificColor
lmaps.symbols.symbol_type = SymbolType.Text
for lmap, color, character in zip(lmaps, cols, chars):
lmap.line.color = color
lmap.symbols.fill_color = color
lmap.symbols.symbol().text = character
plot.view.fit()
# save image to file
tp.export.save_png('linemap_symbols_text.png', 600, supersample=3)
.. figure:: /_static/images/linemap_symbols_text.png
:width: 300px
:figwidth: 300px
"""
def __init__(self, parent, svarg=sv.SYMBOLSHAPE):
super().__init__(parent, svarg)
self._sv += [sv.ASCIISHAPE]
@property
def text(self):
"""The ASCII character to use as the symbol to show
.. note:: This is limited to a single character.
Example usage::
>>> from tecplot.constant import SymbolType
>>> symbols = plot.linemap(0).symbols
>>> symbols.symbol_type = SymbolType.Text
>>> symbols.symbol().text = 'X'
"""
return self._get_style(str, sv.ASCIICHAR)
@text.setter
def text(self, value):
self._set_style(str(value)[0], sv.ASCIICHAR)
@property
def use_base_font(self):
"""`bool`: Use the base typeface when rendering text-based symbols.
When `False`, the ``font_override`` attribute takes effect::
>>> from tecplot.constant import SymbolType, Font
>>> symbols = plot.linemap(0).symbols
>>> symbols.symbol_type = SymbolType.Text
>>> symbols.symbol().use_base_font = False
>>> symbols.symbol().font_override = Font.Greek
"""
return self._get_style(bool, sv.USEBASEFONT)
@use_base_font.setter
def use_base_font(self, value):
self._set_style(bool(value), sv.USEBASEFONT)
@property
def font_override(self):
"""`constant.Font`: Typeface to use when rendering text-based symbols.
Possible values: `constant.Font.Greek`, `constant.Font.Math` or
`constant.Font.UserDefined`.
The ``use_base_font`` attribute must be set to `False`::
>>> from tecplot.constant import SymbolType, Font
>>> symbols = plot.linemap(0).symbols
>>> symbols.symbol_type = SymbolType.Text
>>> symbols.symbol().use_base_font = False
>>> symbols.symbol().font_override = Font.Greek
"""
return self._get_style(Font, sv.FONTOVERRIDE)
@font_override.setter
def font_override(self, value):
if __debug__:
valid_typefaces = [Font.Greek, Font.Math, Font.UserDefined]
if value not in valid_typefaces:
msg = 'font_override must be one of: '
msg += ' '.join(str(x) for x in valid_typefaces)
raise TecplotLogicError(msg)
self._set_style(Font(value), sv.FONTOVERRIDE)
[docs]
class TextScatterSymbol(TextSymbol):
"""Text character for scatter plots.
Only a single character can be used.
.. code-block:: python
:emphasize-lines: 14,23-26,29-30
from os import path
import tecplot as tp
from tecplot.constant import (Color, PlotType, PointsToPlot, SymbolType,
GeomShape, FillMode)
examples_dir = tp.session.tecplot_examples_directory()
infile = path.join(examples_dir, 'SimpleData', 'HeatExchanger.plt')
dataset = tp.data.load_tecplot(infile)
frame = tp.active_frame()
frame.plot_type = PlotType.Cartesian2D
plot = frame.plot()
plot.show_shade = True
plot.show_scatter = True
# get handle to a collection of all fieldmaps
fmaps = plot.fieldmaps()
fmaps.points.points_to_plot = PointsToPlot.SurfaceCellCenters
fmaps.points.step = (4,4)
fmaps.shade.color = Color.LightBlue
fmaps.scatter.fill_mode = FillMode.UseSpecificColor
fmaps.scatter.fill_color = Color.Yellow
fmaps.scatter.size = 3
fmaps.scatter.symbol_type = SymbolType.Text
for i, fmap in enumerate(fmaps):
fmap.scatter.color = Color((i % 4) + 13)
fmap.scatter.symbol().text = hex(i)[-1]
tp.export.save_png('fieldmap_scatter_text.png', 600, supersample=3)
.. figure:: /_static/images/fieldmap_scatter_text.png
:width: 300px
:figwidth: 300px
"""
@tecutil.inherited_property(TextSymbol)
def text(self):
"""The ASCII character to use as the symbol to show
.. note:: This is limited to a single character.
Example usage::
>>> from tecplot.constant import SymbolType
>>> scatter = plot.fieldmap(0).scatter
>>> scatter.symbol_type = SymbolType.Text
>>> scatter.symbol().text = 'X'
"""
@tecutil.inherited_property(TextSymbol)
def use_base_font(self):
"""`bool`: Use the base typeface when rendering text-based scatter.
When `False`, the ``font_override`` attribute takes effect::
>>> from tecplot.constant import SymbolType, Font
>>> scatter = plot.fieldmap(0).scatter
>>> scatter.symbol_type = SymbolType.Text
>>> scatter.symbol().use_base_font = False
>>> scatter.symbol().font_override = Font.Greek
"""
@tecutil.inherited_property(TextSymbol)
def font_override(self):
"""`constant.Font`: Typeface to use when rendering text-based scatter.
Possible values: `constant.Font.Greek`, `constant.Font.Math` or
`constant.Font.UserDefined`.
The ``use_base_font`` attribute must be set to `False`::
>>> from tecplot.constant import SymbolType, Font
>>> scatter = plot.fieldmap(0).scatter
>>> scatter.symbol_type = SymbolType.Text
>>> scatter.symbol().use_base_font = False
>>> scatter.symbol().font_override = Font.Math
"""
[docs]
class GeometrySymbol(Symbol):
"""Geometric shape for linemap symbols.
.. code-block:: python
:emphasize-lines: 24,30
from os import path
import tecplot as tp
from tecplot.constant import (PlotType, Color, GeomShape, SymbolType,
FillMode)
examples_dir = tp.session.tecplot_examples_directory()
infile = path.join(examples_dir, 'SimpleData', 'Rainfall.dat')
dataset = tp.data.load_tecplot(infile)
frame = tp.active_frame()
frame.plot_type = PlotType.XYLine
plot = frame.plot()
plot.show_symbols = True
cols = [Color.DeepRed, Color.Blue, Color.Fern]
shapes = [GeomShape.Square, GeomShape.Circle, GeomShape.Del]
lmaps = plot.linemaps()
lmaps.show = True
lmaps.symbols.show = True
lmaps.symbols.size = 4.5
lmaps.symbols.fill_mode = FillMode.UseSpecificColor
lmaps.symbols.symbol_type = SymbolType.Geometry
for lmap, color, shape in zip(lmaps, cols, shapes):
lmap.line.color = color
lmap.symbols.color = color
lmap.symbols.fill_color = color
lmap.symbols.symbol().shape = shape
plot.view.fit()
# save image to file
tp.export.save_png('linemap_symbols_geometry.png', 600, supersample=3)
.. figure:: /_static/images/linemap_symbols_geometry.png
:width: 300px
:figwidth: 300px
"""
@property
def shape(self):
"""`GeomShape`: Geometric shape to use when plotting linemap symbols.
Possible values: `Square <GeomShape.Square>`, `Del`, `Grad`, `RTri`,
`LTri`, `Diamond`, `Circle <GeomShape.Circle>`, `Cube`, `Sphere`,
`Octahedron`, `Point <GeomShape.Point>`.
Example usage::
>>> from tecplot.constant import SymbolType, GeomShape
>>> symbols = plot.linemap(0).symbols
>>> symbols.symbol_type = SymbolType.Geometry
>>> symbols.symbol().shape = GeomShape.Diamond
"""
return self._get_style(GeomShape, sv.GEOMSHAPE)
@shape.setter
def shape(self, value):
self._set_style(GeomShape(value), sv.GEOMSHAPE)
[docs]
class GeometryScatterSymbol(GeometrySymbol):
"""Geometric shape for scatter plots.
.. code-block:: python
:emphasize-lines: 13,22-26,29-31
from os import path
import tecplot as tp
from tecplot.constant import (Color, PlotType, PointsToPlot, SymbolType,
GeomShape, FillMode)
examples_dir = tp.session.tecplot_examples_directory()
infile = path.join(examples_dir, 'SimpleData', 'HeatExchanger.plt')
dataset = tp.data.load_tecplot(infile)
frame = tp.active_frame()
frame.plot_type = PlotType.Cartesian2D
plot = frame.plot()
plot.show_scatter = True
# get handle to a collection of all fieldmaps
fmaps = plot.fieldmaps()
points = fmaps.points
points.points_to_plot = PointsToPlot.SurfaceCellCenters
points.step = (2,2)
scatter = fmaps.scatter
scatter.fill_mode = FillMode.UseSpecificColor
scatter.size = 2
scatter.line_thickness = 0.5
scatter.symbol_type = SymbolType.Geometry
for i, fmap in enumerate(fmaps):
fmap.scatter.symbol().shape = GeomShape(i%7)
fmap.scatter.color = Color(i)
fmap.scatter.fill_color = Color(i + plot.num_fieldmaps)
tp.export.save_png('fieldmap_scatter_geometry.png', 600, supersample=3)
.. figure:: /_static/images/fieldmap_scatter_geometry.png
:width: 300px
:figwidth: 300px
"""
@tecutil.inherited_property(GeometrySymbol)
def shape(self):
"""`GeomShape`: Geometric shape to use when plotting scatter points.
Possible values: `Square <GeomShape.Square>`, `Del`, `Grad`, `RTri`,
`LTri`, `Diamond`, `Circle <GeomShape.Circle>`, `Cube`, `Sphere`,
`Octahedron`, `Point <GeomShape.Point>`.
Example usage::
>>> from tecplot.constant import SymbolType, GeomShape
>>> scatter = plot.fieldmap(0).scatter
>>> scatter.symbol_type = SymbolType.Geometry
>>> scatter.symbol().shape = GeomShape.Diamond
"""
[docs]
class ScatterReferenceSymbol(session.Style):
"""Reference symbol for scatter plots.
.. note::
The reference scatter symbol is only shown when the scatter symbols are
sized by a `Variable` in the `Dataset <data.Dataset>`.
.. code-block:: python
:emphasize-lines: 17-22
from os import path
import tecplot as tp
from tecplot.constant import *
examples_dir = tp.session.tecplot_examples_directory()
infile = path.join(examples_dir, 'SimpleData', 'HeatExchanger.plt')
dataset = tp.data.load_tecplot(infile)
frame = tp.active_frame()
frame.plot_type = PlotType.Cartesian2D
plot = frame.plot()
plot.contour(0).variable = dataset.variable('T(K)')
plot.show_scatter = True
plot.scatter.variable = dataset.variable('P(N)')
plot.scatter.reference_symbol.show = True
plot.scatter.reference_symbol.symbol().shape = GeomShape.Circle
plot.scatter.reference_symbol.magnitude = plot.scatter.variable.max()
plot.scatter.reference_symbol.color = Color.Green
plot.scatter.reference_symbol.fill_color = Color.Green
plot.scatter.reference_symbol.position = (20, 81)
frame.add_text('Size of dots indicate relative pressure', (23, 80))
for z in dataset.zones():
scatter = plot.fieldmap(z).scatter
scatter.symbol_type = SymbolType.Geometry
scatter.symbol().shape = GeomShape.Circle
scatter.fill_mode = FillMode.UseSpecificColor
scatter.fill_color = plot.contour(0)
scatter.color = plot.contour(0)
scatter.size_by_variable = True
# ensure consistent output between interactive (connected) and batch
plot.contour(0).levels.reset_to_nice()
tp.export.save_png('scatter_reference_symbol.png')
.. figure:: /_static/images/scatter_reference_symbol.png
:width: 300px
:figwidth: 300px
"""
def __init__(self, scatter):
self.scatter = scatter
super().__init__(scatter._sv, sv.REFSCATSYMBOL, **scatter._kw)
@property
def show(self):
"""`bool`: Display a reference scatter symbol on the plot.
Example usage::
>>> plot.fieldmap(0).scatter.size_by_variable = True
>>> plot.scatter.variable = dataset.variable('s')
>>> plot.scatter.reference_symbol.show = True
"""
return self._get_style(bool, sv.SHOW)
@show.setter
def show(self, value):
self._set_style(bool(value), sv.SHOW)
@property
def color(self):
"""`Color`: The `Color` of the reference symbol.
Example usage::
>>> from tecplot.constant import Color
>>> plot.scatter.reference_symbol.color = Color.Blue
"""
return self._get_style(Color, sv.COLOR)
@color.setter
def color(self, value):
self._set_style(Color(value), sv.COLOR)
@property
def filled(self):
"""`bool`: Fill the background area behind the reference symbol.
The background can be filled with a color or disabled (made
transparent) by setting this property to `False`::
>>> plot.scatter.reference_symbol.filled = True
"""
return self._get_style(bool, sv.ISFILLED)
@filled.setter
def filled(self, value):
self._set_style(bool(value), sv.ISFILLED)
@property
def fill_color(self):
"""`Color`: The fill `Color` of the reference symbol.
Example usage::
>>> from tecplot.constant import Color
>>> plot.scatter.reference_symbol.fill_color = Color.Blue
"""
return self._get_style(Color, sv.FILLCOLOR)
@fill_color.setter
def fill_color(self, value):
self._set_style(Color(value), sv.FILLCOLOR)
@property
def position(self):
"""`tuple`: The :math:`(x, y)` position of the reference symbol.
This position is in `Frame <layout.Frame>` percentage units::
>>> plot.scatter.reference_symbol.position = (50, 50)
"""
return session.XY(self, sv.XYPOS)
@position.setter
def position(self, values):
session.XY(self, sv.XYPOS)[:] = values
@property
def magnitude(self):
"""`float`: Symbol size relative to data variable ranges.
Example usage::
>>> plot.scatter.reference_symbol.magnitude = 10.0
"""
return self._get_style(float, sv.MAGNITUDE)
@magnitude.setter
def magnitude(self, value):
self._set_style(float(value), sv.MAGNITUDE)
@property
def line_thickness(self):
"""`float`: Edge line thickness for geometry reference symbols.
Example usage::
>>> plot.scatter.reference_symbol.line_thickness = 2.5
"""
return self._get_style(float, sv.LINETHICKNESS)
@line_thickness.setter
def line_thickness(self, value):
self._set_style(float(value), sv.LINETHICKNESS)
@property
def symbol_type(self):
"""`SymbolType`: The type of symbol to display.
Example usage::
>>> from tecplot.constant import SymbolType
>>> reference_symbol = plot.scatter.reference_symbol
>>> reference_symbol.symbol_type = SymbolType.Text
"""
return Symbol(self)._symbol_type
@symbol_type.setter
def symbol_type(self, value):
Symbol(self)._symbol_type = value
[docs]
def symbol(self, symbol_type=None):
"""`TextSymbol` or `GeometrySymbol`: Style control the displayed symbol.
Example usage::
>>> from tecplot.constant import GeomShape
>>> reference_symbol = plot.scatter.reference_symbol
>>> reference_symbol.symbol = GeomShape.Sphere
"""
_dispatch = {
SymbolType.Text: TextSymbol,
SymbolType.Geometry: GeometrySymbol}
return _dispatch[symbol_type or self.symbol_type](self)