pytecplot 1.5.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. pytecplot-1.5.2.dist-info/LICENSE.html +77 -0
  2. pytecplot-1.5.2.dist-info/METADATA +508 -0
  3. pytecplot-1.5.2.dist-info/RECORD +97 -0
  4. pytecplot-1.5.2.dist-info/WHEEL +5 -0
  5. pytecplot-1.5.2.dist-info/top_level.txt +1 -0
  6. tecplot/__init__.py +94 -0
  7. tecplot/annotation/__init__.py +7 -0
  8. tecplot/annotation/annotation.py +223 -0
  9. tecplot/annotation/geometry.py +369 -0
  10. tecplot/annotation/georeference.py +33 -0
  11. tecplot/annotation/image.py +185 -0
  12. tecplot/annotation/iter.py +105 -0
  13. tecplot/annotation/polyline.py +381 -0
  14. tecplot/annotation/text.py +744 -0
  15. tecplot/constant.py +401 -0
  16. tecplot/data/__init__.py +34 -0
  17. tecplot/data/array.py +645 -0
  18. tecplot/data/create.py +1 -0
  19. tecplot/data/dataset.py +1809 -0
  20. tecplot/data/extract.py +544 -0
  21. tecplot/data/face_neighbors.py +494 -0
  22. tecplot/data/facemap.py +814 -0
  23. tecplot/data/load.py +2075 -0
  24. tecplot/data/nodemap.py +577 -0
  25. tecplot/data/operate.py +928 -0
  26. tecplot/data/query.py +334 -0
  27. tecplot/data/save.py +343 -0
  28. tecplot/data/variable.py +280 -0
  29. tecplot/data/zone.py +841 -0
  30. tecplot/exception.py +201 -0
  31. tecplot/export/__init__.py +13 -0
  32. tecplot/export/animation.py +521 -0
  33. tecplot/export/export_setup.py +318 -0
  34. tecplot/export/image.py +577 -0
  35. tecplot/export/print_setup.py +218 -0
  36. tecplot/export/time_animation.py +607 -0
  37. tecplot/extension/__init__.py +14 -0
  38. tecplot/extension/ipython.py +68 -0
  39. tecplot/layout/__init__.py +20 -0
  40. tecplot/layout/frame.py +1285 -0
  41. tecplot/layout/layout.py +488 -0
  42. tecplot/layout/page.py +541 -0
  43. tecplot/legend/__init__.py +4 -0
  44. tecplot/legend/contour_legend.py +516 -0
  45. tecplot/legend/legend.py +141 -0
  46. tecplot/legend/line_legend.py +66 -0
  47. tecplot/legend/rgb_coloring_legend.py +291 -0
  48. tecplot/legend/scatter_legend.py +136 -0
  49. tecplot/macro.py +339 -0
  50. tecplot/plot/__init__.py +62 -0
  51. tecplot/plot/axes.py +881 -0
  52. tecplot/plot/axis.py +1350 -0
  53. tecplot/plot/blanking.py +584 -0
  54. tecplot/plot/contour.py +1302 -0
  55. tecplot/plot/effects.py +162 -0
  56. tecplot/plot/fieldmap.py +2159 -0
  57. tecplot/plot/grid.py +758 -0
  58. tecplot/plot/isosurface.py +1167 -0
  59. tecplot/plot/labels.py +338 -0
  60. tecplot/plot/linemap.py +1905 -0
  61. tecplot/plot/linking.py +489 -0
  62. tecplot/plot/plot.py +1791 -0
  63. tecplot/plot/rgb_coloring.py +281 -0
  64. tecplot/plot/scatter.py +396 -0
  65. tecplot/plot/slice.py +1544 -0
  66. tecplot/plot/streamtrace.py +1949 -0
  67. tecplot/plot/symbol.py +567 -0
  68. tecplot/plot/ticks.py +666 -0
  69. tecplot/plot/title.py +380 -0
  70. tecplot/plot/vector.py +679 -0
  71. tecplot/plot/view.py +868 -0
  72. tecplot/session/__init__.py +112 -0
  73. tecplot/session/aux_data.py +276 -0
  74. tecplot/session/config.py +92 -0
  75. tecplot/session/session.py +425 -0
  76. tecplot/session/state_changed.py +225 -0
  77. tecplot/session/style.py +504 -0
  78. tecplot/tecutil/__init__.py +16 -0
  79. tecplot/tecutil/arglist.py +230 -0
  80. tecplot/tecutil/captured_output.py +177 -0
  81. tecplot/tecutil/constant.py +1312 -0
  82. tecplot/tecutil/index_set.py +118 -0
  83. tecplot/tecutil/lock.py +36 -0
  84. tecplot/tecutil/message_pb2.py +39 -0
  85. tecplot/tecutil/preamble.py +54 -0
  86. tecplot/tecutil/stringlist.py +114 -0
  87. tecplot/tecutil/sv.py +1662 -0
  88. tecplot/tecutil/tecutil.py +12402 -0
  89. tecplot/tecutil/tecutil_client.py +627 -0
  90. tecplot/tecutil/tecutil_connector.py +937 -0
  91. tecplot/tecutil/tecutil_rpc.py +6845 -0
  92. tecplot/tecutil/util.py +332 -0
  93. tecplot/text/__init__.py +3 -0
  94. tecplot/text/font.py +224 -0
  95. tecplot/text/label_format.py +374 -0
  96. tecplot/text/textbox.py +106 -0
  97. tecplot/version.py +41 -0
@@ -0,0 +1,1285 @@
1
+ import contextlib
2
+ import ctypes
3
+ import logging
4
+ import numbers
5
+
6
+ from ..tecutil import _tecutil, sv
7
+ from ..constant import *
8
+ from ..exception import *
9
+ from .. import annotation, constant, plot, session, tecutil
10
+
11
+
12
+ log = logging.getLogger(__name__)
13
+
14
+
15
+ class Frame(session.Style):
16
+ """`Frame <tecplot.layout.Frame>` object within a `Page <tecplot.layout.Page>`, holding onto a `Dataset <data.Dataset>` and a `Plot`.
17
+
18
+ Parameters:
19
+ uid (`int`, optional): This must be a *valid* unique ID
20
+ number pointing internally to a Frame object or `None`. A new
21
+ `Frame <tecplot.layout.Frame>` is created if set to `None`. (default: `None`)
22
+ page (`Page <tecplot.layout.Page>`, optional): The destination `Page <tecplot.layout.Page>` of this newly
23
+ created `Frame <tecplot.layout.Frame>`. If `None`, the currently active `Page <tecplot.layout.Page>` is used.
24
+ (default: `None`)
25
+
26
+ Warning:
27
+ Though it is possible to create a `Frame <tecplot.layout.Frame>` object using the
28
+ constructor, it is usually sufficient to obtain a frame through
29
+ `tecplot.active_frame()` or `Page.frame()`. One can also create a
30
+ `Frame <tecplot.layout.Frame>` using a `Page <tecplot.layout.Page>` handle with `Page.add_frame()`.
31
+
32
+ The concept of the `Frame <tecplot.layout.Frame>` is central to understanding the
33
+ |Tecplot Engine|. The `Frame <tecplot.layout.Frame>` is what connects a `Dataset <data.Dataset>` to a `Plot`
34
+ handle from which one manipulates the desired image as well as accessing
35
+ the attached data:
36
+
37
+ .. code-block:: python
38
+
39
+ import tecplot
40
+
41
+ frame = tecplot.active_frame()
42
+
43
+ # will print: 'Frame "Frame 001"'
44
+ print(frame)
45
+ """
46
+
47
+ page = None
48
+ """The `Page <tecplot.layout.Page>` containing this Frame.
49
+
50
+ This provides access to the parent `Page <tecplot.layout.Page>`:
51
+
52
+ .. code-block:: python
53
+
54
+ import tecplot
55
+
56
+ frame = tecplot.active_frame()
57
+ page = frame.page
58
+
59
+ # Will print: "Page 001"
60
+ print(page.name)
61
+ """
62
+
63
+ def __init__(self, uid, page):
64
+ self.page = page
65
+ self.uid = uid
66
+ """The internal unique ID number of this Frame."""
67
+ super().__init__(sv.FRAMELAYOUT, uniqueid=self.uid)
68
+
69
+ def __str__(self):
70
+ """Brief string representation.
71
+
72
+ Returns:
73
+ `str`: Brief representation of this `Frame <tecplot.layout.Frame>`.
74
+
75
+ Example:
76
+
77
+ .. code-block:: python
78
+
79
+ import tecplot
80
+ frame = tecplot.active_frame()
81
+
82
+ # will print: 'Frame: "Frame 001"'
83
+ print(frame)
84
+ """
85
+ return 'Frame: "{name}"'.format(name=self.name)
86
+
87
+ def __repr__(self):
88
+ """Executable string representation.
89
+
90
+ Returns:
91
+ `str`: Internal representation of this `Frame <tecplot.layout.Frame>`.
92
+
93
+ The string returned can be executed to generate an identical
94
+ copy of this `Frame <tecplot.layout.Frame>` object:
95
+
96
+ .. code-block:: python
97
+
98
+ import tecplot
99
+ from tecplot.layout import Frame, Page
100
+
101
+ frame = tecplot.active_frame()
102
+
103
+ '''
104
+ The "repr" string of the Frame is executable code.
105
+ The following will print: "Frame(uid=11, page=Page(uid=1))"
106
+ '''
107
+ print(repr(frame))
108
+
109
+ frame2 = None
110
+ exec('frame2 = '+repr(frame))
111
+
112
+ '''
113
+ At this point, frame2 is just another handle to
114
+ the exact same frame object in the Tecplot Engine
115
+ '''
116
+ assert frame2 == frame
117
+ """
118
+ return 'Frame(uid={uid}, page={page})'.format(uid=self.uid,
119
+ page=repr(self.page))
120
+
121
+ def __eq__(self, other):
122
+ """Checks for `Frame <tecplot.layout.Frame>` equality in the |Tecplot Engine|.
123
+
124
+ Returns:
125
+ `bool`: `True` if the unique ID numbers are the same for both
126
+ `Frames <tecplot.layout.Frame>`.
127
+
128
+ Example:
129
+
130
+ .. code-block:: python
131
+
132
+ import tecplot
133
+
134
+ page = tecplot.active_page()
135
+ frame1 = page.active_frame()
136
+ frame2 = page.add_frame()
137
+
138
+ assert not (frame1 == frame2)
139
+ assert page.active_frame() == frame2
140
+ """
141
+ return self.uid == other.uid
142
+
143
+ @property
144
+ def position(self):
145
+ """`tuple`: ``(x,y)`` position of the `Frame <tecplot.layout.Frame>` in inches.
146
+
147
+ The `Frame <tecplot.layout.Frame>` x position is relative to the left side of the paper.
148
+ The `Frame <tecplot.layout.Frame>` y position is relative to the top of the paper.
149
+
150
+ If x is `None`, the `Frame <tecplot.layout.Frame>` x position is not changed.
151
+ If y is `None`, the `Frame <tecplot.layout.Frame>` y position is not changed.
152
+
153
+ Set `Frame <tecplot.layout.Frame>` position 1 inch from the left side of the paper
154
+ and two inches from the top of the paper::
155
+
156
+ >>> tp.active_frame().position=(1.0, 2.0)
157
+
158
+ Move the active `Frame <tecplot.layout.Frame>` one inch to the right::
159
+
160
+ >>> tp.active_frame().position=(tp.active_frame().position.x+1, None)
161
+ """
162
+ return session.XY(self, sv.XYPOS)
163
+
164
+ @position.setter
165
+ def position(self, pos):
166
+ session.XY(self, sv.XYPOS)[:] = pos
167
+
168
+ @property
169
+ def aux_data(self):
170
+ """Auxiliary data for this frame.
171
+
172
+ Returns:
173
+ `AuxData`
174
+
175
+ This is the auxiliary data attached to the frame. Such data is written
176
+ to the layout file by default and can be retrieved later. Example
177
+ usage::
178
+
179
+ >>> aux = tp.active_frame().aux_data
180
+ >>> aux['Result'] = '3.14159'
181
+ >>> print(aux['Result'])
182
+ 3.14159
183
+ """
184
+ return session.AuxData(self, AuxDataObjectType.Frame)
185
+
186
+ def texts(self):
187
+ """Get an iterator for all `Text` objects in the frame.
188
+
189
+ This example shows how to obtain a list of all red `Text` objects::
190
+
191
+ >>> from tecplot.constant import Color
192
+ >>> all_red_text_objects = [T for T in tp.active_frame().texts()
193
+ ... if T.color == Color.Red]
194
+ """
195
+ return annotation.TextIterator(self)
196
+
197
+ def geometries(self):
198
+ """Get an iterator for all geometry objects in the frame.
199
+
200
+ This method provides access to all geometric shape instances attached
201
+ to this `Frame <tecplot.layout.Frame>`. This includes `Circle`, `Polyline2D`, `Polyline3D` and
202
+ all similar objects::
203
+
204
+ >>> for geom in frame.geometries():
205
+ ... print(type(geom))
206
+ <class 'tecplot.annotation.geometry.Circle'>
207
+ <class 'tecplot.annotation.polyline.Polyline2D'>
208
+ """
209
+ shapefilter = annotation.GeometryIterator.ShapeFilter
210
+ return annotation.GeometryIterator(shapefilter, self)
211
+
212
+ def images(self):
213
+ """Get an iterator for all image objects in the frame.
214
+
215
+ This method provides access to all `Image` and `GeoreferencedImage`
216
+ instances attached to this `Frame <tecplot.layout.Frame>`::
217
+
218
+ >>> for image in frame.images():
219
+ ... print(image.filename)
220
+ image1.png
221
+ image2.png
222
+ """
223
+ imagefilter = annotation.GeometryIterator.ImageFilter
224
+ return annotation.GeometryIterator(imagefilter, self)
225
+
226
+ @contextlib.contextmanager
227
+ def activated(self):
228
+ """Context for temporarily activating this `Frame <tecplot.layout.Frame>`.
229
+
230
+ Example:
231
+
232
+ .. code-block:: python
233
+
234
+ import tecplot
235
+
236
+ page = tecplot.active_page()
237
+ frame1 = page.active_frame()
238
+ frame2 = page.add_frame()
239
+
240
+ assert frame2.active
241
+
242
+ with frame1.activated():
243
+ # frame1 is active only during this context
244
+ assert frame1.active
245
+ # there is only one frame active at a time
246
+ assert not frame2.active
247
+
248
+ assert frame2.active
249
+ """
250
+ frame_uid = _tecutil.FrameGetActiveID()
251
+ if self.uid == frame_uid:
252
+ yield
253
+ else:
254
+ page_uid = _tecutil.PageGetUniqueID()
255
+ self.activate()
256
+ try:
257
+ yield
258
+ finally:
259
+ with tecutil.lock():
260
+ if _tecutil.PageGetUniqueID() != page_uid:
261
+ _tecutil.PageSetCurrentByUniqueID(page_uid)
262
+ _tecutil.FrameActivateByUniqueID(frame_uid)
263
+
264
+ @tecutil.lock()
265
+ def load_stylesheet(self, filename, plot_style=True, text=True, geom=True,
266
+ streams=True, contours=True, frame_geom=False,
267
+ merge=False):
268
+ """Apply a stylesheet settings file to this frame.
269
+
270
+ Parameters:
271
+ filename (`str`): The path to a stylesheet file. (See note
272
+ below conerning absolute and relative paths.)
273
+ plot_style (`bool`, optional): Apply the stylesheet's
274
+ plot style. (default: `True`)
275
+ text (`bool`, optional): Include the stylesheet's text
276
+ objects. (default: `True`)
277
+ geom (`bool`, optional): Include the stylesheet's
278
+ geometry objects. (default: `True`)
279
+ streams (`bool`, optional): Include the stylesheet's
280
+ stream traces. (default: `True`)
281
+ contours (`bool`, optional): Include the stylesheet's
282
+ contour levels. (default: `True`)
283
+ frame_geom (`bool`, optional): Apply the stylesheet's
284
+ frame position and size. (default: `False`)
285
+ merge (`bool`, optional): Merge with the frame's current
286
+ style. (default: `False`)
287
+
288
+ .. note:: **Absolute and relative paths with PyTecplot**
289
+
290
+ Relative paths, when used within the PyTecplot API are always from
291
+ Python's current working directory which can be obtained by calling
292
+ :func:`os.getcwd()`. This is true for batch and `connected
293
+ <tecplot.session.connect()>` modes. One exception to this is paths
294
+ within a macro command or file which will be relative to the
295
+ |Tecplot Engine|'s home directory, which is typically the |Tecplot
296
+ 360| installation directory. Finally, when connected to a remote
297
+ (non-local) instance of Tecplot 360, only absolute paths are
298
+ allowed.
299
+
300
+ Note that backslashes must be escaped which is especially important
301
+ for windows paths such as ``"C:\\\\Users"`` or
302
+ ``"\\\\\\\\server\\\\path"`` which will resolve to ``"C:\\Users"``
303
+ and ``"\\\\server\\path"`` respectively. Alternatively, one may use
304
+ Python's raw strings: ``r"C:\\Users"`` and ``r"\\\\server\\path"``
305
+
306
+ Example usage::
307
+
308
+ >>> frame = tecplot.active_frame()
309
+ >>> frame.load_stylesheet('my_style.sty')
310
+ """
311
+ filepath = tecutil.normalize_path(filename)
312
+ with self.activated():
313
+ log.debug('Applying style from {} to frame'.format(filepath))
314
+ if not _tecutil.ReadStylesheet(filepath, plot_style, text, geom,
315
+ streams, contours, merge,
316
+ frame_geom):
317
+ raise TecplotSystemError()
318
+
319
+ @tecutil.lock()
320
+ def save_stylesheet(self, filename, plot_style=True, aux_data=True,
321
+ text=True, geom=True, streams=True, contours=True,
322
+ defaults=False, relative_paths=True, compress=False):
323
+ """Save the frame's current style to a file.
324
+
325
+ Parameters:
326
+ filename (`str`): The path to a stylesheet file. (See note
327
+ below conerning absolute and relative paths.)
328
+ plot_style (`bool`, optional): Include the frame's plot
329
+ style. (default: `True`)
330
+ aux_data (`bool`, optional): Include auxiliary data.
331
+ (default: `True`)
332
+ text (`bool`, optional): Include text objects. (default:
333
+ `True`)
334
+ geom (`bool`, optional): Include geometry objects.
335
+ (default: `True`)
336
+ streams (`bool`, optional): Include stream traces.
337
+ (default: `True`)
338
+ contours (`bool`, optional): Include contour levels.
339
+ (default: `True`)
340
+ defaults (`bool`, optional): Include all factory defaults
341
+ used by the current style. (default: `False`)
342
+ relative_paths (`bool`, optional): Use relative paths.
343
+ (default: `True`)
344
+ compress (`bool`, optional): Compress the output of the
345
+ style. (default: `False`)
346
+
347
+ .. note:: **Absolute and relative paths with PyTecplot**
348
+
349
+ Relative paths, when used within the PyTecplot API are always from
350
+ Python's current working directory which can be obtained by calling
351
+ :func:`os.getcwd()`. This is true for batch and `connected
352
+ <tecplot.session.connect()>` modes. One exception to this is paths
353
+ within a macro command or file which will be relative to the
354
+ |Tecplot Engine|'s home directory, which is typically the |Tecplot
355
+ 360| installation directory. Finally, when connected to a remote
356
+ (non-local) instance of Tecplot 360, only absolute paths are
357
+ allowed.
358
+
359
+ Note that backslashes must be escaped which is especially important
360
+ for windows paths such as ``"C:\\\\Users"`` or
361
+ ``"\\\\\\\\server\\\\path"`` which will resolve to ``"C:\\Users"``
362
+ and ``"\\\\server\\path"`` respectively. Alternatively, one may use
363
+ Python's raw strings: ``r"C:\\Users"`` and ``r"\\\\server\\path"``
364
+
365
+ Example usage::
366
+
367
+ >>> frame = tecplot.active_frame()
368
+ >>> frame.save_stylesheet('my_style.sty')
369
+ """
370
+ filepath = tecutil.normalize_path(filename)
371
+ with self.activated():
372
+ with tecutil.ArgList() as arglist:
373
+ arglist.update((
374
+ (sv.FNAME, str(filepath)),
375
+ (sv.INCLUDEPLOTSTYLE, bool(plot_style)),
376
+ (sv.INCLUDEAUXDATA, bool(aux_data)),
377
+ (sv.INCLUDETEXT, bool(text)),
378
+ (sv.INCLUDEGEOM, bool(geom)),
379
+ (sv.INCLUDESTREAMPOSITIONS, bool(streams)),
380
+ (sv.INCLUDECONTOURLEVELS, bool(contours)),
381
+ (sv.INCLUDEFACTORYDEFAULTS, bool(defaults)),
382
+ (sv.USERELATIVEPATHS, bool(relative_paths)),
383
+ (sv.COMPRESS, bool(compress))))
384
+ if not _tecutil.WriteStylesheetX(arglist):
385
+ raise TecplotSystemError()
386
+
387
+ @property
388
+ def name(self):
389
+ """`str`: Returns or sets the name.
390
+
391
+ This is the name used when searching for `Frame <tecplot.layout.Frame>` objects in
392
+ `Page.frames` and `Page.frame`. It does not have to be unique,
393
+ even for multiple frames in a single `Page <tecplot.layout.Page>`:
394
+
395
+ .. code-block:: python
396
+
397
+ import tecplot
398
+
399
+ frame = tecplot.active_frame()
400
+ frame.name = '3D Data View'
401
+
402
+ # will print: "this frame: 3D Data View"
403
+ print('this frame:', frame.name)
404
+ """
405
+ with self.activated():
406
+ return _tecutil.FrameGetName()[1]
407
+
408
+ @name.setter
409
+ @tecutil.lock()
410
+ def name(self, name):
411
+ with self.activated():
412
+ _tecutil.FrameSetName(name)
413
+
414
+ @property
415
+ def active(self):
416
+ """Checks if this `Frame <tecplot.layout.Frame>` is active.
417
+
418
+ Returns:
419
+ `bool`: `True` if this `Frame <tecplot.layout.Frame>` is the active `Frame <tecplot.layout.Frame>`.
420
+ """
421
+ return self.uid == _tecutil.FrameGetActiveID()
422
+
423
+ @property
424
+ def current(self):
425
+ return self.uid == _tecutil.FrameGetUniqueID()
426
+
427
+ @tecutil.lock()
428
+ def activate(self):
429
+ """Causes this `Frame <tecplot.layout.Frame>` to become active.
430
+
431
+ The parent `Page <tecplot.layout.Page>` is implicitly "activated" as a side-effect of this
432
+ operation:
433
+
434
+ .. code-block:: python
435
+
436
+ import tecplot
437
+
438
+ page1 = tecplot.active_page()
439
+ frame1 = page1.active_frame()
440
+ page2 = tecplot.add_page()
441
+ frame2 = page2.active_frame()
442
+ assert not (frame1.active and page1.active)
443
+ assert frame2.active and page2.active
444
+
445
+ frame1.activate()
446
+ assert not (frame2.active or page2.active)
447
+ assert frame1.active and page1.active
448
+ """
449
+ if not self.active:
450
+ if self.page is not None:
451
+ self.page.activate()
452
+ if not _tecutil.FrameActivateByUniqueID(self.uid):
453
+ err = 'could not activate frame with uid {0}'.format(self.uid)
454
+ raise TecplotSystemError(err)
455
+
456
+ @property
457
+ def plot_type(self):
458
+ """`constant.PlotType`: Returns or sets the current plot type.
459
+
460
+ A `Frame <tecplot.layout.Frame>` can have only one active plot type at any given time. The
461
+ types are enumerated by `constant.PlotType`:
462
+
463
+ .. code-block:: python
464
+
465
+ import os
466
+ import tecplot
467
+ from tecplot.constant import PlotType
468
+
469
+ frame = tecplot.active_frame()
470
+ assert frame.plot_type is PlotType.Sketch
471
+
472
+ install_dir = tecplot.session.tecplot_install_directory()
473
+ infile = os.path.join(install_dir, 'examples', 'SimpleData', 'SpaceShip.lpk')
474
+ tecplot.load_layout(infile)
475
+
476
+ frame = tecplot.active_frame()
477
+ assert frame.plot_type is PlotType.Cartesian3D
478
+
479
+ frame.plot_type = PlotType.Cartesian2D
480
+ assert frame.plot_type is PlotType.Cartesian2D
481
+
482
+ .. note:: Plot type cannot be set to `constant.PlotType.Automatic`.
483
+ """
484
+ return _tecutil.FrameGetPlotTypeForFrame(self.uid)
485
+
486
+ @plot_type.setter
487
+ @tecutil.lock()
488
+ def plot_type(self, plot_type):
489
+ with self.activated():
490
+ try:
491
+ res = _tecutil.FrameSetPlotType(plot_type.value)
492
+ except TecplotSystemError as err:
493
+ if not self.has_dataset:
494
+ res = SetValueReturnCode.ContextError1
495
+ else:
496
+ raise err
497
+ if res not in [SetValueReturnCode.Ok,
498
+ SetValueReturnCode.DuplicateValue]:
499
+ if res is SetValueReturnCode.ContextError1:
500
+ raise TecplotSystemError('no dataset attached to frame')
501
+ raise TecplotSystemError(res)
502
+
503
+ def plot(self, plot_type=PlotType.Active):
504
+ """The primary `Plot` style-control object.
505
+
506
+ Returns:
507
+ `Plot`:
508
+ One of the possible `Plot` subclasses, depending on the
509
+ ``plot_type`` specified. By default, the active plot
510
+ type, obtained from `Frame.plot_type`, is used.
511
+
512
+ The `Plot` object is the handle through which one can manipulate the
513
+ style and visual representation of the `Dataset <data.Dataset>`. Possible return types
514
+ are: `SketchPlot`, `Cartesian2DFieldPlot`, `Cartesian3DFieldPlot`,
515
+ `PolarLinePlot` and `XYLinePlot`. Each of these have their own specific
516
+ set of attributes and methods:
517
+
518
+ .. code-block:: python
519
+
520
+ import os
521
+ import tecplot
522
+ from tecplot.constant import PlotType
523
+
524
+ install_dir = tecplot.session.tecplot_install_directory()
525
+ infile = os.path.join(install_dir, 'examples', 'SimpleData', 'SpaceShip.lpk')
526
+ tecplot.load_layout(infile)
527
+
528
+ frame = tecplot.active_frame()
529
+ assert frame.plot_type is PlotType.Cartesian3D
530
+
531
+ plot3d = frame.plot()
532
+ plot3d.show_contour = True
533
+ """
534
+ if plot_type is PlotType.Active:
535
+ plot_type = None
536
+ _dispatch = {
537
+ PlotType.Cartesian2D: plot.Cartesian2DFieldPlot,
538
+ PlotType.Cartesian3D: plot.Cartesian3DFieldPlot,
539
+ PlotType.XYLine: plot.XYLinePlot,
540
+ PlotType.PolarLine: plot.PolarLinePlot,
541
+ PlotType.Sketch: plot.SketchPlot}
542
+ return _dispatch[plot_type or self.plot_type](self)
543
+
544
+ @tecutil.lock()
545
+ def move_to_bottom(self):
546
+ """Moves `Frame <tecplot.layout.Frame>` behind all others in `Page <tecplot.layout.Page>`.
547
+ """
548
+ _tecutil.FrameMoveToBottomByUniqueID(self.uid)
549
+
550
+ @tecutil.lock()
551
+ def move_to_top(self):
552
+ """Moves `Frame <tecplot.layout.Frame>` in front of all others in `Page <tecplot.layout.Page>`.
553
+ """
554
+ _tecutil.FrameMoveToTopByUniqueID(self.uid)
555
+
556
+ @tecutil.lock()
557
+ def active_zones(self, *zones):
558
+ """Returns or sets the active `Zones <data_access>`.
559
+
560
+ Parameters:
561
+ zones (`Zones <data_access>`, optional): The `Zone <data_access>`
562
+ objects, which must be in the `Dataset <data.Dataset>` attached to this
563
+ `Frame <tecplot.layout.Frame>`, that will be activated. All other `Zones
564
+ <data_access>` will be deactivated.
565
+
566
+ Returns:
567
+ `Zones <data_access>`:
568
+ This will return a generator of active `Zones <data_access>` in
569
+ this `Frame <tecplot.layout.Frame>`.
570
+
571
+ This should only be used on frames with an active plot type that
572
+ contains a dataset with at least one zone.
573
+ """
574
+ if __debug__:
575
+ if self.plot_type is PlotType.Sketch:
576
+ err = 'Active plot type is Sketch which has no active zones.'
577
+ raise TecplotLogicError(err)
578
+ if not self.has_dataset:
579
+ raise TecplotLogicError('Frame has no dataset.')
580
+ if self.dataset.num_zones == 0:
581
+ raise TecplotLogicError('Dataset has no zones.')
582
+
583
+ with self.activated():
584
+ if zones:
585
+ with tecutil.IndexSet(*zones) as zoneset:
586
+ _tecutil.ZoneSetActive(zoneset, AssignOp.Equals.value)
587
+ else:
588
+ zoneset = _tecutil.ZoneGetActiveForFrame(self.uid)
589
+ zones = [self.dataset.zone(i) for i in zoneset]
590
+ zoneset.dealloc()
591
+ return zones
592
+
593
+ @tecutil.lock()
594
+ def delete_geometry(self, geom):
595
+ """Delete a geometry or image annotation object from the `Frame <tecplot.layout.Frame>`.
596
+
597
+ Parameters:
598
+ geom (`Circle`, `Image` or similar instance): The annotation
599
+ instance to be removed from the `Frame <tecplot.layout.Frame>`.
600
+
601
+ .. warning::
602
+ After the annotation is deleted, all handles to it will no longer
603
+ be valid and all accessing any properties of the object will result
604
+ in a `TecplotLogicError` being raised.
605
+
606
+ Example usage:
607
+
608
+ .. code-block:: python
609
+ :emphasize-lines: 6
610
+
611
+ import tecplot
612
+ from tecplot.constant import CoordSys
613
+
614
+ frame = tecplot.active_frame()
615
+ rectangle = frame.add_rectangle((0.5, 0.5), (0.1, 0.2), CoordSys.Frame)
616
+ frame.delete_geometry(rectangle)
617
+ """
618
+ with self.activated():
619
+ _tecutil.GeomDelete(geom.uid)
620
+
621
+ @tecutil.lock()
622
+ def delete_image(self, img):
623
+ """Delete an image annotation object from the `Frame <tecplot.layout.Frame>`.
624
+
625
+ Parameters:
626
+ img (`Image` or `GeoreferencedImage`): The annotation instance to
627
+ be removed from the `Frame <tecplot.layout.Frame>`.
628
+
629
+ .. warning::
630
+ After the annotation is deleted, all handles to it will no longer
631
+ be valid and all accessing any properties of the object will result
632
+ in a `TecplotLogicError` being raised.
633
+
634
+ .. seealso:: `delete_geometry()`
635
+ """
636
+ return self.delete_geometry(img)
637
+
638
+ @tecutil.lock()
639
+ def delete_text(self, text):
640
+ """Delete a `text <annotation.Text>` object from a frame.
641
+
642
+ When deleted, the text object is no longer displayed in the frame and is
643
+ permanently invalid. To display the text in the frame again,
644
+ a new text object must be created by calling `add_text`.
645
+
646
+ .. warning::
647
+ Use this method with care.
648
+ After a text object has been deleted by calling this method,
649
+ it is no longer valid, and all properties of the deleted text
650
+ object will throw `TecplotLogicError` when accessed.
651
+
652
+ Example usage:
653
+
654
+ .. code-block:: python
655
+
656
+ import tecplot as tp
657
+
658
+ text = tp.active_frame().add_text("abc")
659
+ tp.active_frame().delete_text(text)
660
+
661
+ # The text object is no longer valid.
662
+ # Any property access will throw TecplotLogicError
663
+ try:
664
+ print(text.text_string)
665
+ except tp.exception.TecplotLogicError as e:
666
+ print(e)
667
+
668
+ .. seealso:: `add_text`
669
+ """
670
+ with self.activated():
671
+ _tecutil.TextDelete(text.uid)
672
+
673
+ @tecutil.lock()
674
+ def add_image(self, filename, position, height):
675
+ """Add an image to the `Frame <tecplot.layout.Frame>`.
676
+
677
+ Parameters:
678
+ filename (`str`): The image source file. The format of this file
679
+ must be Microsoft Windows Bitmap (*.bmp), JPEG (*.jpg or
680
+ *.jpeg) or Portable Network Graphics (*.png).
681
+ position (`tuple` of `floats <float>`): Position :math:`(x, y)` of
682
+ the image in percentage frame coordinates.
683
+ height (`float`): The initial size, or height, of the image in
684
+ percentage frame units. The initial width in frame units is set
685
+ automatically based on the width to height aspect ratio of the
686
+ image.
687
+
688
+ Returns:
689
+ `annotation.Image`
690
+
691
+ This example adds an image to the upper left quadrant of the frame::
692
+
693
+ >>> frame = tp.active_frame()
694
+ >>> img = frame.add_image('myimage.png', (0, 50), 50)
695
+ """
696
+ x, y = (float(p) for p in position)
697
+ gid = _tecutil.GeomImageCreate(filename, x, y, height)
698
+ if not gid:
699
+ raise TecplotSystemError()
700
+ return annotation.Image(gid, self)
701
+
702
+ @tecutil.lock()
703
+ def add_georeferenced_image(self, image_filename, world_filename):
704
+ """Add a geographic reference image and world file to the `Frame <tecplot.layout.Frame>`.
705
+
706
+ Parameters:
707
+ image_filename (`str`): The image source file.
708
+ world_filename (`str`): The world file associated with the image.
709
+
710
+ Returns:
711
+ `annotation.GeoreferencedImage`
712
+
713
+ Example usage::
714
+
715
+ >>> frame = tp.active_frame()
716
+ >>> imgfile = 'region.png'
717
+ >>> worldfile = 'region.pgw'
718
+ >>> geoimg = frame.add_georeferenced_image(imgfile, worldfile)
719
+ """
720
+ gid = _tecutil.GeoRefImageCreate(image_filename, world_filename)
721
+ if not gid:
722
+ raise TecplotSystemError()
723
+ return annotation.GeoreferencedImage(gid, self)
724
+
725
+ @tecutil.lock()
726
+ def add_circle(self, center, radius, coord_sys):
727
+ """Place a circle annotation on the `Frame <tecplot.layout.Frame>`.
728
+
729
+ Parameters:
730
+ center (`tuple` of `floats <float>`): Position :math:`(x, y)` of
731
+ the center of the circle in the coordinates specified by
732
+ **coord_sys**.
733
+ radius (`float`): The size of the radius in the coordinates
734
+ specified by **coord_sys**.
735
+ coord_sys (`CoordSys`): The coordinate system to use for position
736
+ and size of this annotation.
737
+
738
+ Returns:
739
+ `annotation.Circle`
740
+
741
+ Example usage:
742
+
743
+ .. code-block:: python
744
+
745
+ import tecplot
746
+ from tecplot.constant import CoordSys
747
+
748
+ frame = tecplot.active_frame()
749
+ circle = frame.add_circle((0.2, 0.2), 0.1, CoordSys.Frame)
750
+
751
+ .. seealso:: `add_ellipse`, `add_rectangle`, `add_square`,
752
+ `add_polyline`
753
+ """
754
+ x, y = (float(i) for i in center)
755
+ coord_sys = constant.CoordSys(coord_sys)
756
+ gid = _tecutil.GeomCircleCreate(coord_sys.value, x, y, float(radius))
757
+ if not gid:
758
+ raise TecplotSystemError()
759
+ return annotation.Circle(gid, self)
760
+
761
+ @tecutil.lock()
762
+ def add_ellipse(self, center, size, coord_sys):
763
+ """Place an ellipse annotation on the `Frame <tecplot.layout.Frame>`.
764
+
765
+ Parameters:
766
+ center (`tuple` of `floats <float>`): Position :math:`(x, y)` of
767
+ the ellipse in the coordinates specified by **coord_sys**.
768
+ size (`tuple` of `floats <float>`): Lengths :math:`(h_{axis},
769
+ v_{axis})` of the horizontal and vertical axes in the
770
+ coordinates specified by **coord_sys**. Both lengths must be
771
+ non-zero.
772
+ coord_sys (`CoordSys`): The coordinate system to use for position
773
+ and size of this annotation.
774
+
775
+ Returns:
776
+ `annotation.Ellipse`
777
+
778
+ Example usage:
779
+
780
+ .. code-block:: python
781
+
782
+ import tecplot
783
+ from tecplot.constant import CoordSys
784
+
785
+ frame = tecplot.active_frame()
786
+ ellipse = frame.add_ellipse((0.5, 0.5), (0.1, 0.2), CoordSys.Frame)
787
+
788
+ .. seealso:: `add_circle`, `add_rectangle`, `add_square`,
789
+ `add_polyline`
790
+ """
791
+ x, y = (float(i) for i in center)
792
+ haxis, vaxis = (float(i) for i in size)
793
+ coord_sys = constant.CoordSys(coord_sys)
794
+ gid = _tecutil.GeomEllipseCreate(coord_sys.value, x, y, haxis, vaxis)
795
+ if not gid:
796
+ raise TecplotSystemError()
797
+ return annotation.Ellipse(gid, self)
798
+
799
+ @tecutil.lock()
800
+ def add_rectangle(self, corner, size, coord_sys):
801
+ """Place a rectangle annotation on the `Frame <tecplot.layout.Frame>`.
802
+
803
+ Parameters:
804
+ center (`tuple` of `floats <float>`): Position :math:`(x, y)` of
805
+ the rectangle in the coordinates specified by **coord_sys**.
806
+ size (`tuple` of `floats <float>`): Size :math:`(width, height)` of
807
+ the rectangle in the coordinates specified by **coord_sys**.
808
+ coord_sys (`CoordSys`): The coordinate system to use for position
809
+ and size of this annotation.
810
+
811
+ Returns:
812
+ `annotation.Rectangle`
813
+
814
+ Example usage:
815
+
816
+ .. code-block:: python
817
+
818
+ import tecplot
819
+ from tecplot.constant import CoordSys
820
+
821
+ frame = tecplot.active_frame()
822
+ rectangle = frame.add_rectangle((0.5, 0.5), (0.1, 0.2), CoordSys.Frame)
823
+
824
+ .. seealso:: `add_circle`, `add_ellipse`, `add_square`,
825
+ `add_polyline`
826
+ """
827
+ x, y = (float(i) for i in corner)
828
+ w, h = (float(i) for i in size)
829
+ coord_sys = constant.CoordSys(coord_sys)
830
+ gid = _tecutil.GeomRectangleCreate(coord_sys.value, x, y, w, h)
831
+ if not gid:
832
+ raise TecplotSystemError()
833
+ return annotation.Rectangle(gid, self)
834
+
835
+ @tecutil.lock()
836
+ def add_square(self, corner, size, coord_sys):
837
+ """Place a square annotation on the `Frame <tecplot.layout.Frame>`.
838
+
839
+ Parameters:
840
+ corner (`tuple` of `floats <float>`): Position :math:`(x, y)` of
841
+ the lower-left corner of the square in the coordinates
842
+ specified by **coord_sys**.
843
+ size (`float`): Side-length of the square in the coordinates
844
+ specified by **coord_sys**.
845
+ coord_sys (`CoordSys`): The coordinate system to use for position
846
+ and size of this annotation.
847
+
848
+ Returns:
849
+ `annotation.Square`
850
+
851
+ Example usage:
852
+
853
+ .. code-block:: python
854
+
855
+ import tecplot
856
+ from tecplot.constant import CoordSys
857
+
858
+ frame = tecplot.active_frame()
859
+ square = frame.add_square((0.2, 0.2), 0.1, CoordSys.Frame)
860
+
861
+ .. seealso:: `add_circle`, `add_ellipse`, `add_rectangle`,
862
+ `add_polyline`
863
+ """
864
+ x, y = (float(i) for i in corner)
865
+ coord_sys = constant.CoordSys(coord_sys)
866
+ gid = _tecutil.GeomSquareCreate(coord_sys.value, x, y, float(size))
867
+ if not gid:
868
+ raise TecplotSystemError()
869
+ return annotation.Square(gid, self)
870
+
871
+ @tecutil.lock()
872
+ def add_polyline(self, *points, **kwargs):
873
+ """Create a polyline annotation on this `Frame <tecplot.layout.Frame>`.
874
+
875
+ Parameters:
876
+ *points (`lists <list>` of points): Arrays of :math:`(x, y)` or
877
+ :math:`(x, y, z)` positions of the points along this polyline
878
+ in the coordinate system specified by **coord_sys**. If
879
+ multiple lists are provided, they must be of the same dimension
880
+ (2D or 3D), though they may be of different lengths.
881
+
882
+ Keyword Parameters:
883
+ coord_sys (`CoordSys`, optional): The coordinate system to use for
884
+ the positions of this annotation. Only 2D polylines may use a
885
+ coordinate system other than the data-coordinates ("grid").
886
+ (default: `CoordSys.Grid`)
887
+
888
+ Returns:
889
+ One of `annotation.Polyline2D`, `annotation.Polyline3D`,
890
+ `annotation.MultiPolyline2D` or `annotation.MultiPolyline3D`.
891
+
892
+ Example usage:
893
+
894
+ .. code-block:: python
895
+
896
+ import tecplot
897
+
898
+ points = [ [1, 2, 3],
899
+ [2, 4, 9],
900
+ [3, 8, 27], ]
901
+
902
+ frame = tecplot.active_frame()
903
+ polyline = frame.add_polyline(points)
904
+
905
+ .. seealso:: `add_circle`, `add_ellipse`, `add_rectangle`, `add_square`
906
+ """
907
+ coord_sys = kwargs.get('coord_sys', constant.CoordSys.Grid)
908
+ coord_sys = constant.CoordSys(coord_sys)
909
+ num_lines = len(points)
910
+ dims = [len(l[0]) for l in points]
911
+ if any(d != dims[0] for d in dims):
912
+ msg = 'dimensions of all polylines must be the same'
913
+ raise TecplotLogicError(msg)
914
+ lengths = (ctypes.c_int64 * num_lines)(*[len(l) for l in points])
915
+
916
+ if dims[0] == 3:
917
+ if __debug__:
918
+ if coord_sys not in [constant.CoordSys.Grid,
919
+ constant.CoordSys.Grid3D]:
920
+ msg = '3D polylines must be in "Grid" coordinates'
921
+ raise TecplotLogicError(msg)
922
+ gid = _tecutil.Geom3DMPolyCreate(num_lines, lengths)
923
+ if not gid:
924
+ raise TecplotSystemError()
925
+ polyline = annotation.MultiPolyline3D(gid, self)
926
+ else:
927
+ gid = _tecutil.Geom2DMPolyCreate(coord_sys.value, num_lines, lengths)
928
+ if not gid:
929
+ raise TecplotSystemError()
930
+ polyline = annotation.MultiPolyline2D(gid, self)
931
+
932
+ for l, p in zip(polyline, points):
933
+ l[:] = p
934
+
935
+ if num_lines == 1:
936
+ if dims[0] == 3:
937
+ polyline = annotation.Polyline3D(0, polyline)
938
+ else:
939
+ polyline = annotation.Polyline2D(0, polyline)
940
+
941
+ return polyline
942
+
943
+ @tecutil.lock()
944
+ def add_text(self, text, position=None, coord_sys=None, text_type=None,
945
+ typeface=None, bold=None, italic=None, size_units=None,
946
+ size=None, color=None, angle=None, line_spacing=None,
947
+ anchor=None, box_type=None, line_thickness=None,
948
+ box_color=None, fill_color=None, margin=None, zone=None):
949
+ """Adds a `text <annotation.Text>` to a `Frame <tecplot.layout.Frame>`.
950
+
951
+ Parameters:
952
+ text (`str`): The text to add to the `Frame <tecplot.layout.Frame>`.
953
+ The text string must have a non-zero length.
954
+ position (`tuple` of `floats <float>` (x,y), optional): The
955
+ position of the anchor as a percentage of the
956
+ specified coordinates. (default: (0,0))
957
+ coord_sys (`CoordSys`, optional): Coordinate system used to
958
+ position the anchor of the text object. The possible values
959
+ are: `CoordSys.Grid` or `CoordSys.Frame`. (default:
960
+ `CoordSys.Frame`)
961
+ text_type (`TextType`, optional): Type of text object to create.
962
+ Options are `TextType.Regular` (default) and `TextType.LaTeX`.
963
+ If set to `TextType.LaTeX`, most style-related options will be
964
+ saved but ignored when the text is rendered. These options will
965
+ only be used if the type of the text object is later changed to
966
+ `TextType.Regular`.
967
+ typeface (`str`, optional): The typeface name. For
968
+ consistency across various platforms, Tecplot guarantees that
969
+ the following standard typeface names are available:
970
+ "Helvetica", "Times", "Courier", "Greek", "Math", and "User
971
+ Defined". Other typefaces may or may not be available depending
972
+ on the TrueType fonts available. If the typeface name or style
973
+ is not available, a suitable replacement will be selected.
974
+ (default: "Helvetica")
975
+ bold (`bool`, optional): Use the bold variation of the
976
+ specified typeface. (default: `True`)
977
+ italic (`bool`, optional): Use the italic variation of
978
+ the specified typeface. (default: `False`)
979
+ size_units (`Units`, optional): Text sizing units. Possible
980
+ values are: `Units.Grid`, `Units.Frame` or `Units.Point`.
981
+ (default: `Units.Point`)
982
+ size (`float`, optional): Text height in the specified units.
983
+ (default: 14)
984
+ color (`Color`, optional): Color of the text
985
+ (default: `Color.Black`)
986
+ angle (`float`, optional): Angle of the text baseline in degrees
987
+ from -360 to 360. (default: 0)
988
+ line_spacing (`float`, optional): Line spacing in units of line
989
+ size. Can take values from 0 to 50. (default: 1)
990
+ anchor (`TextAnchor`, optional): Anchor position with respect to
991
+ the text box. Possible values are: `TextAnchor.Left`,
992
+ `TextAnchor.Center`, `TextAnchor.Right`,
993
+ `TextAnchor.MidLeft`, `TextAnchor.MidCenter`,
994
+ `TextAnchor.MidRight`, `TextAnchor.HeadLeft`,
995
+ `TextAnchor.HeadCenter`, `TextAnchor.HeadRight`,
996
+ `TextAnchor.OnSide` (default: `TextAnchor.Left`)
997
+ box_type (`constant.TextBox`, optional): Type of text box can be one
998
+ of: `constant.TextBox.None_`, `constant.TextBox.Filled` or `constant.TextBox.Hollow`.
999
+ (default: `constant.TextBox.None_`)
1000
+ line_thickness (`float`, optional): Text box boarder line
1001
+ thickness may be a value in the range from 0.0001 to 100.
1002
+ (default: 0.1)
1003
+ box_color (`Color`, optional): Text box border line color. See
1004
+ `Color` for possible values. (default: `Color.Black`)
1005
+ fill_color (`Color`, optional): Text box fill color. See `Color`
1006
+ for possible values. (default: `White`)
1007
+ margin (`float`, optional): Margin between the text and text
1008
+ box. May be in the range from 0 to 2000. (default: 20)
1009
+ zone (`Zone <data_access>`, optional): `Zone <data_access>` or
1010
+ `XYLinemap` to which the text will be attached. (default: None)
1011
+
1012
+ Returns:
1013
+ `annotation.Text`: The resulting `text box <annotation.Text>`
1014
+ object.
1015
+
1016
+ Example:
1017
+
1018
+ .. code-block:: python
1019
+ :emphasize-lines: 5-6
1020
+
1021
+ import tecplot
1022
+ from tecplot.constant import Color
1023
+
1024
+ frame = tecplot.active_frame()
1025
+ frame.add_text('Hello, World!', position=(35, 50),
1026
+ bold=True, italic=False, color=Color.Blue)
1027
+
1028
+ .. seealso:: `add_latex`, `delete_text`
1029
+ """
1030
+ if __debug__:
1031
+ tecutil.check_arglist_argtypes(
1032
+ 'frame.add_text',
1033
+ ([tuple], [position], ['position']),
1034
+ ([CoordSys], [coord_sys], ['coord_sys']),
1035
+ ([str], [typeface, text], ['typeface', 'text']),
1036
+ ([bool], [bold, italic], ['bold', 'italic']),
1037
+ ([Units], [size_units], ['size_units']),
1038
+ ([numbers.Number], [size, angle, line_thickness, margin,
1039
+ line_spacing],
1040
+ ['size', 'angle', 'line_thickness', 'margin',
1041
+ 'line_spacing']),
1042
+ ([Color], [color, box_color, fill_color],
1043
+ ['color', 'text_color', 'fill_color']),
1044
+ ([TextAnchor], [anchor], ['anchor']),
1045
+ ([TextBox], [box_type], ['box_type']),
1046
+ )
1047
+
1048
+ with tecutil.ArgList() as arglist:
1049
+ if zone is not None:
1050
+ arglist[sv.ATTACHTOZONE] = True
1051
+ arglist[sv.ZONE] = zone.index + 1
1052
+
1053
+ def optional(type_, value):
1054
+ return type_(value) if value is not None else None
1055
+
1056
+ # Note that TecUtil calls SV_TEXTCOLOR the color of the text,
1057
+ # and SV_COLOR as the text *box* color. These names correspond
1058
+ # to the 'color' and 'box_color' parameters.
1059
+ arglist.update((
1060
+ (sv.TEXT, text),
1061
+ (sv.POSITIONCOORDSYS, coord_sys),
1062
+ (sv.ISBOLD, bold),
1063
+ (sv.ISITALIC, italic),
1064
+ (sv.SIZEUNITS, size_units),
1065
+ (sv.ANCHOR, anchor),
1066
+ (sv.COLOR, box_color),
1067
+ (sv.TEXTCOLOR, color),
1068
+ (sv.FILLCOLOR, fill_color),
1069
+ (sv.BOXTYPE, box_type)))
1070
+ arglist[sv.TEXTTYPE] = optional(TextType, text_type)
1071
+ if position is not None:
1072
+ arglist[sv.XPOS] = optional(float, position[0])
1073
+ arglist[sv.YPOS] = optional(float, position[1])
1074
+
1075
+ arglist[sv.HEIGHT] = optional(float, size)
1076
+ arglist[sv.ANGLE] = optional(float, angle)
1077
+ arglist[sv.LINETHICKNESS] = optional(float, line_thickness)
1078
+ arglist[sv.MARGIN] = optional(float, margin)
1079
+ arglist[sv.LINESPACING] = optional(float, line_spacing)
1080
+
1081
+ tid = _tecutil.TextCreateX(arglist)
1082
+ if tid == 0:
1083
+ raise TecplotSystemError()
1084
+ return annotation.Text(tid, self)
1085
+
1086
+ def add_latex(self, text, position=None, coord_sys=None, size_units=None,
1087
+ size=None, anchor=None, zone=None):
1088
+ r"""Adds a `LaTeX text <annotation.Text>` annotation to the Frame.
1089
+
1090
+ LaTeX is a computer language designed for typesetting. The most popular
1091
+ use of LaTeX is math and Greek fonts for technical purposes. See the
1092
+ User Manual for instruction on how to setup LaTeX for use with Tecplot
1093
+ 360. Once LaTeX is configured for the GUI version of Tecplot 360 no
1094
+ additional changes are needed for PyTecplot.
1095
+
1096
+ Parameters:
1097
+ text (`str`): The text to add to the `Frame <tecplot.layout.Frame>`.
1098
+ The text string must have a non-zero length.
1099
+ position (`tuple` of `floats <float>` (x,y), optional): The
1100
+ position of the anchor as a percentage of the
1101
+ specified coordinates. (default: (0,0))
1102
+ coord_sys (`CoordSys`, optional): Coordinate system used to
1103
+ position the anchor of the text object. The possible values
1104
+ are: `CoordSys.Grid` or `CoordSys.Frame`. (default:
1105
+ `CoordSys.Frame`)
1106
+ size_units (`Units`, optional): Text sizing units. Possible
1107
+ values are: `Units.Grid`, `Units.Frame` or `Units.Point`.
1108
+ (default: `Units.Point`)
1109
+ size (`float`, optional): Text height in the specified units.
1110
+ (default: 14)
1111
+ anchor (`TextAnchor`, optional): Anchor position with respect to
1112
+ the text box. Possible values are: `TextAnchor.Left`,
1113
+ `TextAnchor.Center`, `TextAnchor.Right`,
1114
+ `TextAnchor.MidLeft`, `TextAnchor.MidCenter`,
1115
+ `TextAnchor.MidRight`, `TextAnchor.HeadLeft`,
1116
+ `TextAnchor.HeadCenter`, `TextAnchor.HeadRight`,
1117
+ `TextAnchor.OnSide` (default: `TextAnchor.Left`)
1118
+ zone (`Zone <data_access>`, optional): `Zone <data_access>` or
1119
+ `XYLinemap` to which the text will be attached. (default: None)
1120
+
1121
+ Returns:
1122
+ `annotation.Text`: The resulting `text box <annotation.Text>`
1123
+ object.
1124
+
1125
+ Example:
1126
+ .. code-block:: python
1127
+ :emphasize-lines: 5-6
1128
+
1129
+ import tecplot as tp
1130
+ from tecplot.constant import TextAnchor
1131
+
1132
+ frame = tp.active_frame()
1133
+ frame.add_latex(r'$$\zeta(s) = \sum_{n=1}^\infty\frac{1}{n^s}$$',
1134
+ (50,50), size=64, anchor=TextAnchor.Center)
1135
+
1136
+ .. figure:: /_static/images/frame_add_latex.png
1137
+ :width: 300px
1138
+ :figwidth: 300px
1139
+
1140
+ .. seealso:: `add_text`, `delete_text`
1141
+ """
1142
+ return self.add_text(text, position=position, coord_sys=coord_sys,
1143
+ size_units=size_units, size=size, anchor=anchor,
1144
+ zone=zone, text_type=TextType.LaTeX)
1145
+
1146
+ @tecutil.lock()
1147
+ def create_dataset(self, name, var_names=None, reset_style=True):
1148
+ """Create an empty `Dataset <data.Dataset>`.
1149
+
1150
+ This will create a new `Dataset <data.Dataset>` and replace the existing one,
1151
+ destroying all data associated with it.
1152
+
1153
+ Parameters:
1154
+ name (`str`): Title of the new `Dataset <data.Dataset>`. This does not
1155
+ have to be unique.
1156
+ var_names (`list` of `strings <str>`, optional): `Variable`
1157
+ names. This only sets the names and not the data type or
1158
+ location. See `add_variable`. (default: `None`)
1159
+ reset_style (`bool`): Reset style of the active `Frame <tecplot.layout.Frame>`
1160
+ before loading the `Dataset <data.Dataset>`. (default: `True`)
1161
+
1162
+ Returns:
1163
+ `Dataset <data.Dataset>`: The newly created `Dataset <data.Dataset>`.
1164
+
1165
+ .. note:: Relationships between `Frame <tecplot.layout.Frame>` and `Dataset <data.Dataset>`
1166
+
1167
+ A `Frame <tecplot.layout.Frame>` may only hold a single `Dataset <data.Dataset>`, though this `Dataset <data.Dataset>`
1168
+ may be shared between several `Frames <tecplot.layout.Frame>`. Therefore, this
1169
+ method will only *replace* the current dataset when **reset_style**
1170
+ is set to `True` and will fail otherwise. If this `Frame <tecplot.layout.Frame>` already
1171
+ has a `Dataset <data.Dataset>`, it may be more efficient to do one of the following
1172
+ instead:
1173
+
1174
+ * Add a new (blank) frame with `Page.add_frame()` and create
1175
+ a `Dataset <data.Dataset>` for this.
1176
+ * Add new zones to the existing `Dataset <data.Dataset>` with
1177
+ `Dataset.add_ordered_zone()`, `Dataset.add_fe_zone()` or
1178
+ `Dataset.add_poly_zone()`.
1179
+ * Change the existing data `in-place <Array>`.
1180
+
1181
+ .. note:: **Performance considerations for data manipulations.**
1182
+
1183
+ When performing many data-manipulation operations including adding
1184
+ zones, adding variables, modifying field data or connectivity, and
1185
+ especially in connected mode, it is recommended to do this all with
1186
+ the `tecplot.session.suspend()`. This will prevent the Tecplot
1187
+ engine from trying to "keep up" with the changes. Tecplot will be
1188
+ notified of all changes made upon exit of this context. This may
1189
+ result in significant performance gains for long operations.
1190
+
1191
+ """
1192
+ with self.activated():
1193
+ if var_names is not None:
1194
+ var_names = tecutil.StringList(*var_names)
1195
+ try:
1196
+ if not _tecutil.DataSetCreate(name, var_names, reset_style):
1197
+ raise TecplotSystemError()
1198
+ finally:
1199
+ if var_names is not None:
1200
+ var_names.dealloc()
1201
+ return self.dataset
1202
+
1203
+ @property
1204
+ def background_color(self):
1205
+ """`Color`: Color of the background."""
1206
+ return self._get_style(constant.Color, sv.BACKGROUNDCOLOR)
1207
+
1208
+ @background_color.setter
1209
+ def background_color(self, value):
1210
+ self._set_style(constant.Color(value), sv.BACKGROUNDCOLOR)
1211
+
1212
+ @property
1213
+ def border_thickness(self):
1214
+ """`float`: The border thickness in units of `Frame.size_pos_units`."""
1215
+ return self._get_style(float, sv.BORDERTHICKNESS)
1216
+
1217
+ @border_thickness.setter
1218
+ def border_thickness(self, value):
1219
+ self._set_style(float(value), sv.BORDERTHICKNESS)
1220
+
1221
+ @property
1222
+ def height(self):
1223
+ """`float`: The height in units of `Frame.size_pos_units`."""
1224
+ return self._get_style(float, sv.HEIGHT)
1225
+
1226
+ @height.setter
1227
+ def height(self, value):
1228
+ self._set_style(float(value), sv.HEIGHT)
1229
+
1230
+ @property
1231
+ def show_border(self):
1232
+ """`bool`: Show or hide the `Frame <tecplot.layout.Frame>`'s border."""
1233
+ return self._get_style(bool, sv.SHOWBORDER)
1234
+
1235
+ @show_border.setter
1236
+ def show_border(self, value):
1237
+ self._set_style(bool(value), sv.SHOWBORDER)
1238
+
1239
+ @property
1240
+ def show_header(self):
1241
+ """`bool`: Show or hide the `Frame <tecplot.layout.Frame>`'s header in the border."""
1242
+ return self._get_style(bool, sv.SHOWHEADER)
1243
+
1244
+ @show_header.setter
1245
+ def show_header(self, value):
1246
+ self._set_style(bool(value), sv.SHOWHEADER)
1247
+
1248
+ @property
1249
+ def header_background_color(self):
1250
+ """`Color`: The header's background color."""
1251
+ return self._get_style(constant.Color, sv.HEADERCOLOR)
1252
+
1253
+ @header_background_color.setter
1254
+ def header_background_color(self, value):
1255
+ self._set_style(constant.Color(value), sv.HEADERCOLOR)
1256
+
1257
+ @property
1258
+ def size_pos_units(self):
1259
+ """`FrameSizePosUnits`: The units used for size properties.
1260
+
1261
+ Possible values: `Paper`, `Workspace <FrameSizePosUnits.Workspace>`.
1262
+ """
1263
+ return self._get_style(constant.FrameSizePosUnits, sv.FRAMESIZEPOSUNITS)
1264
+
1265
+ @size_pos_units.setter
1266
+ def size_pos_units(self, value):
1267
+ self._set_style(constant.FrameSizePosUnits(value), sv.FRAMESIZEPOSUNITS)
1268
+
1269
+ @property
1270
+ def transparent(self):
1271
+ """`bool`: Use transparency within this `Frame <tecplot.layout.Frame>`."""
1272
+ return self._get_style(bool, sv.ISTRANSPARENT)
1273
+
1274
+ @transparent.setter
1275
+ def transparent(self, value):
1276
+ self._set_style(bool(value), sv.ISTRANSPARENT)
1277
+
1278
+ @property
1279
+ def width(self):
1280
+ """`float`: The width in units of `Frame.size_pos_units`."""
1281
+ return self._get_style(float, sv.WIDTH)
1282
+
1283
+ @width.setter
1284
+ def width(self, value):
1285
+ self._set_style(float(value), sv.WIDTH)