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
tecplot/plot/plot.py ADDED
@@ -0,0 +1,1791 @@
1
+ import contextlib
2
+ import fnmatch
3
+ import re
4
+ import warnings
5
+
6
+ from ..tecutil import _tecutil, _tecutil_connector, sv
7
+ from ..constant import *
8
+ from ..exception import *
9
+ from .. import legend, session, tecutil, text, version
10
+ from .axes import (Cartesian2DFieldAxes, Cartesian3DFieldAxes, SketchAxes,
11
+ PolarLineAxes, XYLineAxes)
12
+ from .contour import ContourGroup
13
+ from .fieldmap import (Cartesian2DFieldmap, Cartesian2DFieldmapCollection,
14
+ Cartesian3DFieldmap, Cartesian3DFieldmapCollection,
15
+ FieldmapCollection)
16
+ from .isosurface import IsosurfaceGroup
17
+ from .streamtrace import StreamtraceRodRibbon, Streamtraces
18
+ from .vector import Vector2D, Vector3D
19
+ from . import (blanking, effects, labels, linking, linemap,
20
+ rgb_coloring, scatter, slice, view)
21
+
22
+
23
+ class Plot(session.Style):
24
+ def __init__(self, frame, *svargs):
25
+ self.frame = frame
26
+ super().__init__(*svargs, uniqueid=frame.uid)
27
+
28
+ def __eq__(self, that):
29
+ return isinstance(that, type(self)) and self.frame == that.frame
30
+
31
+ def __ne__(self, that):
32
+ return not (self == that)
33
+
34
+ @contextlib.contextmanager
35
+ def activated(self):
36
+ """Context to ensure this plot is active.
37
+
38
+ Example usage::
39
+
40
+ >>> from tecplot.constant import PlotType
41
+ >>> frame = tecplot.active_frame()
42
+ >>> frame.plot_type = PlotType.XYLine # set active plot type
43
+ >>> plot = frame.plot(PlotType.Cartesian3D) # get inactive plot
44
+ >>> print(frame.plot_type)
45
+ PlotType.XYLine
46
+ >>> with plot.activated():
47
+ ... print(frame.plot_type) # 3D plot temporarily active
48
+ PlotType.Cartesian3D
49
+ >>> print(frame.plot_type) # original plot type restored
50
+ PlotType.XYLine
51
+ """
52
+ with self.frame.activated():
53
+ orig_plot = self.frame.plot()
54
+ try:
55
+ self.activate()
56
+ yield self
57
+ finally:
58
+ orig_plot.activate()
59
+
60
+
61
+ class SketchPlot(Plot):
62
+ """A plot space with no data attached.
63
+
64
+ .. code-block:: python
65
+ :emphasize-lines: 5,8-9
66
+
67
+ import tecplot as tp
68
+ from tecplot.constant import PlotType
69
+
70
+ frame = tp.active_frame()
71
+ plot = frame.plot(PlotType.Sketch)
72
+
73
+ frame.add_text('Hello, World!', (36, 50), size=34)
74
+ plot.axes.x_axis.show = True
75
+ plot.axes.y_axis.show = True
76
+
77
+ tp.export.save_png('plot_sketch.png', 600, supersample=3)
78
+
79
+ .. figure:: /_static/images/plot_sketch.png
80
+ :width: 300px
81
+ :figwidth: 300px
82
+ """
83
+
84
+ def activate(self):
85
+ """Make this the active plot type on the parent frame.
86
+
87
+ Example usage::
88
+
89
+ >>> from tecplot.constant import PlotType
90
+ >>> plot = frame.plot(PlotType.Sketch)
91
+ >>> plot.activate()
92
+ """
93
+ self.frame.plot_type = PlotType.Sketch
94
+
95
+ @property
96
+ def axes(self):
97
+ """`SketchAxes`: Axes (x and y) for the sketch plot.
98
+
99
+ Example usage::
100
+
101
+ >>> from tecplot.constant import PlotType
102
+ >>> frame.plot_type = PlotType.Sketch
103
+ >>> frame.plot().axes.x_axis.show = True
104
+ """
105
+ return SketchAxes(self)
106
+
107
+ @property
108
+ def linking_between_frames(self):
109
+ """`SketchPlotLinkingBetweenFrames`: Style linking between frames.
110
+
111
+ Example usage::
112
+
113
+ >>> plot.linking_between_frames.group = 1
114
+ >>> plot.linking_between_frames.link_solution_time = True
115
+ """
116
+ return linking.SketchPlotLinkingBetweenFrames(self.frame)
117
+
118
+ @property
119
+ def linking_within_frame(self):
120
+ """`LinkingWithinFrame`: Style linking within the frame.
121
+
122
+ Example usage::
123
+
124
+ >>> plot.linking_within_frame.link_gridline_style = True
125
+ """
126
+ return linking.LinkingWithinFrame(self.frame)
127
+
128
+
129
+ class FieldPlot(Plot):
130
+ """Plot containing data associated with style through fieldmaps.
131
+
132
+ .. code-block:: python
133
+
134
+ from os import path
135
+ import tecplot as tp
136
+ from tecplot.constant import PlotType
137
+
138
+ examples_dir = tp.session.tecplot_examples_directory()
139
+ infile = path.join(examples_dir, 'SimpleData', 'F18.plt')
140
+ dataset = tp.data.load_tecplot(infile)
141
+
142
+ frame = tp.active_frame()
143
+ plot = frame.plot(PlotType.Cartesian3D)
144
+ plot.activate()
145
+ plot.show_contour = True
146
+ plot.use_translucency = True
147
+ plot.contour(0).variable = dataset.variable('S')
148
+
149
+ # ensure consistent output between interactive (connected) and batch
150
+ plot.contour(0).levels.reset_to_nice()
151
+
152
+ # save image to file
153
+ tp.export.save_png('plot_field.png', 600, supersample=3)
154
+
155
+ .. figure:: /_static/images/plot_field.png
156
+ :width: 300px
157
+ :figwidth: 300px
158
+ """
159
+ def __init__(self, frame):
160
+ super().__init__(frame, sv.FIELDLAYERS)
161
+
162
+ def contour(self, index):
163
+ """`ContourGroup`: Plot-local `ContourGroup` style control.
164
+
165
+ Example usage::
166
+
167
+ >>> contour = frame.plot().contour(0)
168
+ >>> contour.colormap_name = 'Magma'
169
+ """
170
+ return ContourGroup(index, self)
171
+
172
+ @property
173
+ def streamtraces(self):
174
+ """`Streamtraces`: Plot-local `streamtrace <Streamtraces>` attributes.
175
+
176
+ Example usage::
177
+
178
+ >>> streamtraces = frame.plot().streamtraces
179
+ >>> streamtraces.color = Color.Blue
180
+ """
181
+ return Streamtraces(self)
182
+
183
+ def slice(self, index):
184
+ tecutil.api_changed('''\
185
+ Access to 3D slice groups from 2D plots has been removed.
186
+ Use frame.plot(PlotType.Cartesian3D).slice() to access
187
+ slice groups.''', '0.13', '2018 R2')
188
+
189
+ def isosurface(self, index):
190
+ tecutil.api_changed('''\
191
+ Access to 3D isosurface groups from 2D plots has been removed.
192
+ Use frame.plot(PlotType.Cartesian3D).isosurface() to access
193
+ isosurface groups.''', '0.13', '2018 R2')
194
+
195
+ @property
196
+ def rgb_coloring(self):
197
+ """`RGBColoring`: RGB contour flooding style control.
198
+
199
+ Example usage::
200
+
201
+ >>> plot.rgb_coloring.red_variable = dataset.variable('gas')
202
+ >>> plot.rgb_coloring.green_variable = dataset.variable('oil')
203
+ >>> plot.rgb_coloring.blue_variable = dataset.variable('water')
204
+ >>> plot.show_contour = True
205
+ >>> plot.fieldmaps().contour.flood_contour_group = plot.rgb_coloring
206
+ """
207
+ return rgb_coloring.RGBColoring(self)
208
+
209
+ @property
210
+ def scatter(self):
211
+ """`Scatter`: Plot-local `Scatter` style control.
212
+
213
+ Example usage::
214
+
215
+ >>> scatter = frame.plot().scatter
216
+ >>> scatter.variable = dataset.variable('P')
217
+ """
218
+ return scatter.Scatter(self)
219
+
220
+ @property
221
+ def show_contour(self):
222
+ """`bool`: Enable contours for this plot.
223
+
224
+ Example usage::
225
+
226
+ >>> frame.plot().show_contour = True
227
+ """
228
+ return self._get_style(bool, sv.SHOWCONTOUR)
229
+
230
+ @show_contour.setter
231
+ def show_contour(self, show):
232
+ self._set_style(bool(show), sv.SHOWCONTOUR)
233
+
234
+ @property
235
+ def show_edge(self):
236
+ """`bool`: Enable zone edge lines for this plot.
237
+
238
+ Example usage::
239
+
240
+ >>> frame.plot().show_edge = True
241
+ """
242
+ return self._get_style(bool, sv.SHOWEDGE)
243
+
244
+ @show_edge.setter
245
+ def show_edge(self, show):
246
+ self._set_style(bool(show), sv.SHOWEDGE)
247
+
248
+ @property
249
+ def show_mesh(self):
250
+ """`bool`: Enable mesh lines for this plot.
251
+
252
+ Example usage::
253
+
254
+ >>> frame.plot().show_mesh = True
255
+ """
256
+ return self._get_style(bool, sv.SHOWMESH)
257
+
258
+ @show_mesh.setter
259
+ def show_mesh(self, show):
260
+ self._set_style(bool(show), sv.SHOWMESH)
261
+
262
+ @property
263
+ def show_scatter(self):
264
+ """`bool`: Enable scatter symbols for this plot.
265
+
266
+ Example usage::
267
+
268
+ >>> frame.plot().show_scatter = True
269
+ """
270
+ return self._get_style(bool, sv.SHOWSCATTER)
271
+
272
+ @show_scatter.setter
273
+ def show_scatter(self, show):
274
+ self._set_style(bool(show), sv.SHOWSCATTER)
275
+
276
+ @property
277
+ def show_shade(self):
278
+ """`bool`: Enable surface shading effect for this plot.
279
+
280
+ Example usage::
281
+
282
+ >>> frame.plot().show_shade = True
283
+ """
284
+ return self._get_style(bool, sv.SHOWSHADE)
285
+
286
+ @show_shade.setter
287
+ def show_shade(self, show):
288
+ self._set_style(bool(show), sv.SHOWSHADE)
289
+
290
+ @property
291
+ def show_slices(self):
292
+ """`bool`: Show slices for this plot.
293
+
294
+ Example usage::
295
+
296
+ >>> frame.plot().show_slices(True)
297
+ """
298
+ with self.frame.activated():
299
+ return session.get_style(bool, sv.SLICELAYERS, sv.SHOW,
300
+ uniqueid=self.frame.uid)
301
+
302
+ @show_slices.setter
303
+ def show_slices(self, show):
304
+ with self.frame.activated():
305
+ session.set_style(bool(show), sv.SLICELAYERS, sv.SHOW,
306
+ uniqueid=self.frame.uid)
307
+
308
+ @property
309
+ def show_isosurfaces(self):
310
+ """`bool`: Show isosurfaces for this plot.
311
+
312
+ Example usage::
313
+
314
+ >>> frame.plot().show_isosurfaces(True)
315
+ """
316
+ with self.frame.activated():
317
+ return session.get_style(bool, sv.ISOSURFACELAYERS, sv.SHOW,
318
+ uniqueid=self.frame.uid)
319
+
320
+ @show_isosurfaces.setter
321
+ def show_isosurfaces(self, show):
322
+ with self.frame.activated():
323
+ session.set_style(bool(show), sv.ISOSURFACELAYERS, sv.SHOW,
324
+ uniqueid=self.frame.uid)
325
+
326
+ @property
327
+ def show_streamtraces(self):
328
+ """`bool`: Enable drawing `Streamtraces` on this plot.
329
+
330
+ Example usage::
331
+
332
+ >>> frame.plot().show_streamtraces = True
333
+ """
334
+ with self.frame.activated():
335
+ return session.get_style(bool, sv.STREAMTRACELAYERS, sv.SHOW,
336
+ uniqueid=self.frame.uid)
337
+
338
+ @show_streamtraces.setter
339
+ def show_streamtraces(self, show):
340
+ with self.frame.activated():
341
+ session.set_style(bool(show), sv.STREAMTRACELAYERS, sv.SHOW,
342
+ uniqueid=self.frame.uid)
343
+
344
+ @property
345
+ def show_vector(self):
346
+ """`bool`: Enable drawing of vectors.
347
+
348
+ Example usage::
349
+
350
+ >>> frame.plot().show_vector = True
351
+ """
352
+ return self._get_style(bool, sv.SHOWVECTOR)
353
+
354
+ @show_vector.setter
355
+ def show_vector(self, show):
356
+ self._set_style(bool(show), sv.SHOWVECTOR)
357
+
358
+ @property
359
+ def num_fieldmaps(self):
360
+ """`int`: Number of all fieldmaps in this plot.
361
+
362
+ Example usage::
363
+
364
+ >>> print(frame.plot().num_fieldmaps)
365
+ 3
366
+ """
367
+ return _tecutil.FieldMapGetCountForFrame(self.frame.uid)
368
+
369
+ def _fieldmap_indices(self, *keys):
370
+ result = set()
371
+ for key in tecutil.flatten_args(*keys):
372
+ if isinstance(key, FieldmapCollection):
373
+ result |= key._indices
374
+ elif isinstance(key, int):
375
+ result.add(key)
376
+ else:
377
+ index = getattr(key, 'index', self.fieldmap_index(key))
378
+ result.add(index)
379
+ return result
380
+
381
+ def fieldmap_index(self, zone):
382
+ """The index of the fieldmap associated with a `Zone <data_access>`.
383
+
384
+ Parameters:
385
+ zone (`Zone <data_access>`): The `Zone <data_access>` object that
386
+ belongs to the `Dataset <data.Dataset>` associated with this plot.
387
+
388
+ Returns:
389
+ `Index`
390
+
391
+ Example usage::
392
+
393
+ >>> fmap_index = plot.fieldmap_index(dataset.zone('Zone'))
394
+ >>> plot.fieldmap(fmap_index).show_mesh = True
395
+ """
396
+ with self.frame.activated():
397
+ return tecutil.Index(_tecutil.ZoneGetFieldMap(zone.index + 1) - 1)
398
+
399
+ @property
400
+ def active_fieldmap_indices(self):
401
+ """`set`: Set of active fieldmaps by index.
402
+
403
+ This example sets the first three fieldmaps active, disabling all
404
+ others. It then turns on scatter symbols for just these three::
405
+
406
+ >>> plot.active_fieldmap_indices = [0, 1, 2]
407
+ >>> plot.fieldmaps(0, 1, 2).scatter.show = True
408
+ """
409
+ return session.get_style(set, sv.ACTIVEFIELDMAPS,
410
+ uniqueid=self.frame.uid)
411
+
412
+ @active_fieldmap_indices.setter
413
+ def active_fieldmap_indices(self, values):
414
+ session.set_style(set(values), sv.ACTIVEFIELDMAPS,
415
+ uniqueid=self.frame.uid)
416
+
417
+ @property
418
+ def num_solution_times(self):
419
+ """`int`: Number of solution times for all active fieldmaps.
420
+
421
+ .. note::
422
+
423
+ This only returns the number of *active* solution times. When
424
+ assigning strands and solution times to zones, the zones are
425
+ placed into an *inactive* fieldmap that must be subsequently
426
+ activated. See example below.
427
+
428
+ .. code-block:: python
429
+
430
+ >>> # place all zones into a single fieldmap (strand: 1)
431
+ >>> # with incrementing solution times
432
+ >>> for time, zone in enumerate(dataset.zones()):
433
+ ... zone.strand = 1
434
+ ... zone.solution_time = time
435
+ ...
436
+ >>> # We must activate the fieldmap to ensure the plot's
437
+ >>> # solution times have been updated. Since we placed
438
+ >>> # all zones into a single fieldmap, we can assume the
439
+ >>> # first fieldmap (index: 0) is the one we want.
440
+ >>> plot.active_fieldmaps += [0]
441
+ >>>
442
+ >>> # now the plot's solution times are available.
443
+ >>> print(plot.num_solution_times)
444
+ 10
445
+ >>> print(plot.solution_times)
446
+ [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
447
+
448
+ .. versionadded:: 2017.2
449
+ Solution time manipulation requires Tecplot 360 2017 R2 or later.
450
+ """
451
+ success, result = _tecutil.SolutionTimeGetNumTimeStepsForFrame(
452
+ self.frame.uid)
453
+ if not success:
454
+ raise TecplotSystemError()
455
+ return result
456
+
457
+ @property
458
+ def solution_times(self):
459
+ """`list` of `floats <float>`: `List <list>` of active solution times.
460
+
461
+ .. note::
462
+
463
+ This only returns the list of *active* solution times. When
464
+ assigning strands and solution times to zones, the zones are placed
465
+ into an *inactive* fieldmap that must be subsequently activated.
466
+ See example below.
467
+
468
+ Example usage::
469
+
470
+ >>> print(plot.solution_times)
471
+ [0.0, 1.0, 2.0]
472
+
473
+ .. versionadded:: 2017.2
474
+ Solution time manipulation requires Tecplot 360 2017 R2 or later.
475
+ """
476
+ res = _tecutil.SolutionTimeGetSolutionTimesForFrame(self.frame.uid)
477
+ success, ntimes, times = res
478
+ if not success:
479
+ raise TecplotSystemError()
480
+ ret = list(times[:ntimes])
481
+ if not _tecutil_connector.connected:
482
+ _tecutil.ArrayDealloc(times)
483
+ return ret
484
+
485
+ @property
486
+ def transient_zone_visibility(self):
487
+ """`TransientZoneVisibility`: Policy to determine transient visibility of zones.
488
+
489
+ Possible values: `ZonesAtOrBeforeSolutionTime`, `ZonesAtSolutionTime`.
490
+
491
+ Example usage::
492
+
493
+ >>> from tecplot.constant import TransientZoneVisibility
494
+ >>> plot.transient_zone_visibility = \\
495
+ ... TransientZoneVisibility.ZonesAtSolutionTime
496
+
497
+ .. versionadded:: 2021.2
498
+ Transient zone visibility requires Tecplot 360 2021 R2 or later.
499
+ """
500
+ if __debug__:
501
+ reqver = (2021, 2)
502
+ if version.sdk_version_info < reqver:
503
+ msg = 'Transient zone visibility requires 2021 R2 or later.'
504
+ raise TecplotOutOfDateEngineError(reqver, msg)
505
+ style = session.Style(sv.GLOBALTIME, **self._kw)
506
+ return style._get_style(TransientZoneVisibility, sv.TRANSIENTZONEVISIBILITY)
507
+
508
+ @transient_zone_visibility.setter
509
+ def transient_zone_visibility(self, value):
510
+ if __debug__:
511
+ reqver = (2021, 2)
512
+ if version.sdk_version_info < reqver:
513
+ msg = 'Transient zone visibility requires 2021 R2 or later.'
514
+ raise TecplotOutOfDateEngineError(reqver, msg)
515
+ style = session.Style(sv.GLOBALTIME, **self._kw)
516
+ style._set_style(TransientZoneVisibility(value), sv.TRANSIENTZONEVISIBILITY)
517
+
518
+ @property
519
+ def solution_time(self):
520
+ """`float`: The current solution time.
521
+
522
+ Example usage::
523
+
524
+ >>> print(plot.solution_times)
525
+ [0.0, 1.0, 2.0]
526
+ >>> plot.solution_time = 1.0
527
+
528
+ .. note:: **Possible side-effect when connected to Tecplot 360.**
529
+
530
+ Changing the solution times in the dataset or modifying the
531
+ active fieldmaps in a frame may trigger a change in the active
532
+ plot's solution time by the Tecplot 360 interface. This is done
533
+ to keep the GUI controls consistent. In batch mode, no such
534
+ side-effect will take place and the user must take care to set
535
+ the plot's solution time with the `plot.solution_time
536
+ <Cartesian3DFieldPlot.solution_time>` or
537
+ `plot.solution_timestep
538
+ <Cartesian3DFieldPlot.solution_timestep>` properties.
539
+
540
+ .. versionadded:: 2017.2
541
+ Solution time manipulation requires Tecplot 360 2017 R2 or later.
542
+ """
543
+ return _tecutil.SolutionTimeGetCurrentForFrame(self.frame.uid)
544
+
545
+ @solution_time.setter
546
+ @tecutil.lock()
547
+ def solution_time(self, value):
548
+ with self.frame.activated():
549
+ res = _tecutil.SolutionTimeSetCurrent(float(value))
550
+ if res not in [SetValueReturnCode.Ok,
551
+ SetValueReturnCode.DuplicateValue]:
552
+ raise TecplotSystemError()
553
+
554
+ @property
555
+ def solution_timestep(self):
556
+ """`int`: The zero-based index of the current solution time.
557
+
558
+ A negative index is interpreted as counting from the end of the
559
+ available solution timesteps. Example usage::
560
+
561
+ >>> print(plot.solution_times)
562
+ [0.0, 1.0, 2.0]
563
+ >>> print(plot.solution_time)
564
+ 0.0
565
+ >>> plot.solution_timestep += 1
566
+ >>> print(plot.solution_time)
567
+ 1.0
568
+
569
+ .. note:: **Possible side-effect when connected to Tecplot 360.**
570
+
571
+ Changing the solution times in the dataset or modifying the
572
+ active fieldmaps in a frame may trigger a change in the active
573
+ plot's solution time by the Tecplot 360 interface. This is done
574
+ to keep the GUI controls consistent. In batch mode, no such
575
+ side-effect will take place and the user must take care to set
576
+ the plot's solution time with the `plot.solution_time
577
+ <Cartesian3DFieldPlot.solution_time>` or
578
+ `plot.solution_timestep
579
+ <Cartesian3DFieldPlot.solution_timestep>` properties.
580
+
581
+ .. versionadded:: 2017.2
582
+ Solution time manipulation requires Tecplot 360 2017 R2 or later.
583
+ """
584
+ success, result = _tecutil.SolutionTimeGetCurrentTimeStepForFrame(
585
+ self.frame.uid)
586
+ if not success:
587
+ raise TecplotSystemError()
588
+ return result - 1
589
+
590
+ @solution_timestep.setter
591
+ def solution_timestep(self, timestep):
592
+ timestep = int(timestep)
593
+ if timestep < 0:
594
+ timestep = self.num_solution_times + timestep
595
+ success, time = _tecutil.SolutionTimeGetSolutionTimeAtTimeStepForFrame(
596
+ self.frame.uid, int(timestep) + 1)
597
+ if not success:
598
+ raise TecplotSystemError()
599
+ self.solution_time = time
600
+
601
+ @property
602
+ def ijk_blanking(self):
603
+ """`IJKBlanking`: Mask off cells by :math:`(i, j, k)` index.
604
+
605
+ Example usage::
606
+
607
+ >>> plot.ijk_blanking.min_percent = (50, 50)
608
+ >>> plot.ijk_blanking.active = True
609
+ """
610
+ return blanking.IJKBlanking(self)
611
+
612
+ @property
613
+ def data_labels(self):
614
+ """`FieldPlotDataLabels`: Node and cell labels.
615
+
616
+ This object controls displaying labels for every node and/or cell in
617
+ the dataset. Example usage::
618
+
619
+ >>> plot.data_labels.show_cell_labels = True
620
+ >>> plot.data_labels.step_index = 10
621
+ """
622
+ return labels.FieldPlotDataLabels(self)
623
+
624
+ @property
625
+ def linking_within_frame(self):
626
+ """`FieldPlotLinkingWithinFrame`: Style linking within the frame.
627
+
628
+ Example usage::
629
+
630
+ >>> plot.linking_within_frame.link_gridline_style = True
631
+ """
632
+ return linking.FieldPlotLinkingWithinFrame(self.frame)
633
+
634
+
635
+ class Cartesian2DFieldPlot(FieldPlot):
636
+ """2D plot containing field data associated with style through fieldmaps.
637
+
638
+ .. code-block:: python
639
+ :emphasize-lines: 10-17,23-24
640
+
641
+ from os import path
642
+ import tecplot as tp
643
+ from tecplot.constant import PlotType
644
+
645
+ examples_dir = tp.session.tecplot_examples_directory()
646
+ infile = path.join(examples_dir, 'SimpleData', 'HeatExchanger.plt')
647
+ dataset = tp.data.load_tecplot(infile)
648
+
649
+ frame = tp.active_frame()
650
+ plot = frame.plot(PlotType.Cartesian2D)
651
+ plot.activate()
652
+
653
+ plot.vector.u_variable = dataset.variable('U(M/S)')
654
+ plot.vector.v_variable = dataset.variable('V(M/S)')
655
+
656
+ plot.contour(2).variable = dataset.variable('T(K)')
657
+ plot.contour(2).colormap_name = 'Sequential - Yellow/Green/Blue'
658
+
659
+ for z in dataset.zones():
660
+ fmap = plot.fieldmap(z)
661
+ fmap.contour.flood_contour_group = plot.contour(2)
662
+
663
+ plot.show_contour = True
664
+ plot.show_vector = True
665
+
666
+ # ensure consistent output between interactive (connected) and batch
667
+ plot.contour(2).levels.reset_to_nice()
668
+
669
+ # save image to file
670
+ tp.export.save_png('plot_field2d.png', 600, supersample=3)
671
+
672
+ .. figure:: /_static/images/plot_field2d.png
673
+ :width: 300px
674
+ :figwidth: 300px
675
+ """
676
+
677
+ def activate(self):
678
+ """Make this the active plot type on the parent frame.
679
+
680
+ Example usage::
681
+
682
+ >>> from tecplot.constant import PlotType
683
+ >>> plot = frame.plot(PlotType.Cartesian2D)
684
+ >>> plot.activate()
685
+ """
686
+ self.frame.plot_type = PlotType.Cartesian2D
687
+
688
+ @property
689
+ def axes(self):
690
+ """`Cartesian2DFieldAxes`: Axes style control for this plot.
691
+
692
+ Example usage::
693
+
694
+ >>> from tecplot.constant import PlotType
695
+ >>> frame.plot_type = PlotType.Cartesian2D
696
+ >>> axes = frame.plot().axes
697
+ >>> axes.x_axis.variable = dataset.variable('U')
698
+ >>> axes.y_axis.variable = dataset.variable('V')
699
+ """
700
+ return Cartesian2DFieldAxes(self)
701
+
702
+ def fieldmap(self, key):
703
+ """Returns a `Cartesian2DFieldmap` by `Zone <data_access>` or index.
704
+
705
+ Parameters:
706
+ key (`Zone <data_access>` or `int`): The `Zone <data_access>` must
707
+ be in the `Dataset <data.Dataset>` attached to the associated frame of this
708
+ plot. A negative index is interpreted as counting from the end
709
+ of the available fieldmaps.
710
+
711
+ Example usage::
712
+
713
+ >>> fmap = plot.fieldmap(dataset.zone(0))
714
+ >>> fmap.scatter.show = True
715
+ """
716
+ if isinstance(key, int):
717
+ index = self.num_fieldmaps + key if key < 0 else key
718
+ else:
719
+ index = self.fieldmap_index(key)
720
+ return Cartesian2DFieldmap(self, index)
721
+
722
+ def fieldmaps(self, *keys):
723
+ """`Cartesian2DFieldmapCollection` by `Zones <data_access>` or indices.
724
+
725
+ Parameters:
726
+ keys (`list` of `Zones <data_access>` or `ints <int>`): The
727
+ `Zones <data_access>` must be in the `Dataset <data.Dataset>` attached to the
728
+ associated frame of this plot. Negative indices are interpreted
729
+ as counting from the end of the available fieldmaps.
730
+
731
+ Example usage::
732
+
733
+ >>> fmaps = plot.fieldmaps(dataset.zone(0), dataset.zone(1))
734
+ >>> fmaps.scatter.show = True
735
+
736
+ .. versionchanged:: 0.9
737
+ `fieldmaps` was changed from a property (0.8 and earlier) to a
738
+ method requiring parentheses.
739
+ """
740
+ indices = self._fieldmap_indices(*keys)
741
+ if not indices:
742
+ indices = range(self.num_fieldmaps)
743
+ return Cartesian2DFieldmapCollection(self, *indices)
744
+
745
+ @property
746
+ def active_fieldmaps(self):
747
+ """`Cartesian2DFieldmapCollection`: Active fieldmaps in this plot.
748
+
749
+ Example usage::
750
+
751
+ >>> plot.active_fieldmaps.vector.show = True
752
+
753
+ .. note:: **Possible side-effect when connected to Tecplot 360.**
754
+
755
+ Changing the solution times in the dataset or modifying the
756
+ active fieldmaps in a frame may trigger a change in the active
757
+ plot's solution time by the Tecplot 360 interface. This is done
758
+ to keep the GUI controls consistent. In batch mode, no such
759
+ side-effect will take place and the user must take care to set
760
+ the plot's solution time with the `plot.solution_time
761
+ <Cartesian3DFieldPlot.solution_time>` or
762
+ `plot.solution_timestep
763
+ <Cartesian3DFieldPlot.solution_timestep>` properties.
764
+ """
765
+ indices = self.active_fieldmap_indices
766
+ return Cartesian2DFieldmapCollection(self, *indices)
767
+
768
+ @active_fieldmaps.setter
769
+ def active_fieldmaps(self, fmaps):
770
+ indices = getattr(fmaps, 'fieldmap_indices', fmaps)
771
+ self.active_fieldmap_indices = indices
772
+
773
+ @property
774
+ def vector(self):
775
+ """`Vector2D`: Vector variable and style control for this plot.
776
+
777
+ Example usage::
778
+
779
+ >>> plot.vector.u_variable = dataset.variable('U')
780
+ """
781
+ return Vector2D(self)
782
+
783
+ @property
784
+ def draw_order(self):
785
+ """`TwoDDrawOrder`: The order in which objects are drawn to the screen.
786
+
787
+ Possible values: `TwoDDrawOrder.ByZone`, `TwoDDrawOrder.ByLayer`.
788
+
789
+ The order is either by `Zone <data_access>` or by visual layer
790
+ (contour, mesh, etc.)::
791
+
792
+ >>> plot.draw_order = TwoDDrawOrder.ByZone
793
+ """
794
+ return self._get_style(TwoDDrawOrder, sv.TWODDRAWORDER)
795
+
796
+ @draw_order.setter
797
+ def draw_order(self, order):
798
+ self._set_style(TwoDDrawOrder(order), sv.TWODDRAWORDER)
799
+
800
+ @property
801
+ def view(self):
802
+ """`Cartesian2DFieldView`: Axes orientation and limits adjustments.
803
+
804
+ Example usage::
805
+
806
+ >>> plot.view.fit()
807
+ """
808
+ return view.Cartesian2DFieldView(self)
809
+
810
+ @property
811
+ def value_blanking(self):
812
+ """`ValueBlanking`: Mask off cells by value.
813
+
814
+ Example usage::
815
+
816
+ >>> plot.value_blanking.constraint(0).comparison_value = 3.14
817
+ >>> plot.value_blanking.constraint(0).active = True
818
+ """
819
+ return blanking.ValueBlankingCartesian2D(self)
820
+
821
+ @property
822
+ def linking_between_frames(self):
823
+ """`Cartesian2DPlotLinkingBetweenFrames`: Style linking between frames.
824
+
825
+ Example usage::
826
+
827
+ >>> plot.linking_between_frames.group = 1
828
+ >>> plot.linking_between_frames.link_solution_time = True
829
+ """
830
+ return linking.Cartesian2DPlotLinkingBetweenFrames(self.frame)
831
+
832
+
833
+ class Cartesian3DFieldPlot(FieldPlot):
834
+ """3D plot containing field data associated with style through fieldmaps.
835
+
836
+ .. code-block:: python
837
+ :emphasize-lines: 10-14
838
+
839
+ from os import path
840
+ import tecplot as tp
841
+ from tecplot.constant import PlotType
842
+
843
+ examples_dir = tp.session.tecplot_examples_directory()
844
+ infile = path.join(examples_dir, 'SimpleData', 'SpaceShip.lpk')
845
+ dataset = tp.load_layout(infile)
846
+
847
+ frame = tp.active_frame()
848
+ plot = frame.plot(PlotType.Cartesian3D)
849
+ plot.activate()
850
+ plot.use_lighting_effect = False
851
+ plot.show_streamtraces = False
852
+ plot.use_translucency = True
853
+
854
+ # ensure consistent output between interactive (connected) and batch
855
+ plot.contour(0).levels.reset_to_nice()
856
+
857
+ # save image to file
858
+ tp.export.save_png('plot_field3d.png', 600, supersample=3)
859
+
860
+ .. figure:: /_static/images/plot_field3d.png
861
+ :width: 300px
862
+ :figwidth: 300px
863
+ """
864
+
865
+ def activate(self):
866
+ """Make this the active plot type on the parent frame.
867
+
868
+ Example usage::
869
+
870
+ >>> from tecplot.constant import PlotType
871
+ >>> plot = frame.plot(PlotType.Cartesian3D)
872
+ >>> plot.activate()
873
+ """
874
+ self.frame.plot_type = PlotType.Cartesian3D
875
+
876
+ @property
877
+ def axes(self):
878
+ """`Cartesian3DFieldAxes`: Axes style control for this plot.
879
+
880
+ Example usage::
881
+
882
+ >>> from tecplot.constant import PlotType
883
+ >>> frame.plot_type = PlotType.Cartesian3D
884
+ >>> axes = frame.plot().axes
885
+ >>> axes.x_axis.variable = dataset.variable('U')
886
+ >>> axes.y_axis.variable = dataset.variable('V')
887
+ >>> axes.z_axis.variable = dataset.variable('W')
888
+ """
889
+ return Cartesian3DFieldAxes(self)
890
+
891
+ def fieldmap(self, key):
892
+ """Returns a `Cartesian3DFieldmap` by `Zone <data_access>` or index.
893
+
894
+ Parameters:
895
+ key (`Zone <data_access>` or `int`): The `Zone
896
+ <data_access>` must be in the `Dataset <data.Dataset>` attached to the
897
+ associated frame of this plot. A negative index is interpreted
898
+ as counting from the end of the available fieldmaps.
899
+
900
+ Example usage::
901
+
902
+ >>> fmap = plot.fieldmap(dataset.zone(0))
903
+ >>> fmap.scatter.show = True
904
+ """
905
+ if isinstance(key, int):
906
+ index = self.num_fieldmaps + key if key < 0 else key
907
+ else:
908
+ index = self.fieldmap_index(key)
909
+ return Cartesian3DFieldmap(self, index)
910
+
911
+ def fieldmaps(self, *keys):
912
+ """`Cartesian3DFieldmapCollection` by `Zones <data_access>` or indices.
913
+
914
+ Parameters:
915
+ keys (`list` of `Zones <data_access>` or `integers <int>`): The
916
+ `Zones <data_access>` must be in the `Dataset <data.Dataset>` attached to the
917
+ associated frame of this plot. Negative indices are interpreted
918
+ as counting from the end of the available fieldmaps.
919
+
920
+ Example usage::
921
+
922
+ >>> fmaps = plot.fieldmaps(dataset.zone(0), dataset.zone(1))
923
+ >>> fmaps.scatter.show = True
924
+
925
+ .. versionchanged:: 0.9
926
+ `fieldmaps` was changed from a property (0.8 and earlier) to a
927
+ method requiring parentheses.
928
+ """
929
+ indices = self._fieldmap_indices(*keys)
930
+ if not indices:
931
+ indices = range(self.num_fieldmaps)
932
+ return Cartesian3DFieldmapCollection(self, *indices)
933
+
934
+ @property
935
+ def active_fieldmaps(self):
936
+ """`Cartesian3DFieldmapCollection`: Active fieldmaps in this plot.
937
+
938
+ Example usage::
939
+
940
+ >>> plot.active_fieldmaps.vector.show = True
941
+
942
+ .. note:: **Possible side-effect when connected to Tecplot 360.**
943
+
944
+ Changing the solution times in the dataset or modifying the
945
+ active fieldmaps in a frame may trigger a change in the active
946
+ plot's solution time by the Tecplot 360 interface. This is done
947
+ to keep the GUI controls consistent. In batch mode, no such
948
+ side-effect will take place and the user must take care to set
949
+ the plot's solution time with the `plot.solution_time
950
+ <Cartesian3DFieldPlot.solution_time>` or
951
+ `plot.solution_timestep
952
+ <Cartesian3DFieldPlot.solution_timestep>` properties.
953
+ """
954
+ indices = self.active_fieldmap_indices
955
+ return Cartesian3DFieldmapCollection(self, *indices)
956
+
957
+ @active_fieldmaps.setter
958
+ def active_fieldmaps(self, fmaps):
959
+ indices = getattr(fmaps, 'fieldmap_indices',
960
+ [getattr(fmap, 'index', fmap) for fmap in fmaps])
961
+ self.active_fieldmap_indices = indices
962
+
963
+ def slice(self, index):
964
+ """`SliceGroup`: Plot-local `slice <SliceGroup>` style control.
965
+
966
+ Example usage::
967
+
968
+ >>> from tecplot.constant import Color
969
+ >>> slice0 = frame.plot().slice(0)
970
+ >>> slice0.mesh.show = True
971
+ >>> slice0.mesh.color = Color.Blue
972
+ """
973
+ return slice.SliceGroup(self, index)
974
+
975
+ def slices(self, *indices):
976
+ """`SliceGroupCollection`: Plot-local slice style control.
977
+
978
+ Example setting setting mesh color of all slices to blue::
979
+
980
+ >>> from tecplot.constant import Color
981
+ >>> slices = frame.plot().slices()
982
+ >>> slices.mesh.show = True
983
+ >>> slices.mesh.color = Color.Blue
984
+
985
+ Example turning on the first two slice's contour layer::
986
+
987
+ >>> slices = frame.plot().slices(0, 1)
988
+ >>> slices.contour.show = True
989
+ """
990
+ return slice.SliceGroupCollection(self, *indices)
991
+
992
+ def isosurface(self, index):
993
+ """`IsosurfaceGroup`: Plot-local `isosurface <IsosurfaceGroup>` settings.
994
+
995
+ Example usage::
996
+
997
+ >>> isosurface_0 = frame.plot().isosurface(0)
998
+ >>> isosurface_0.mesh.color = Color.Blue
999
+ """
1000
+ return IsosurfaceGroup(index, self)
1001
+
1002
+ @property
1003
+ def vector(self):
1004
+ """`Vector3D`: Vector variable and style control for this plot.
1005
+
1006
+ Example usage::
1007
+
1008
+ >>> plot.vector.u_variable = dataset.variable('U')
1009
+ """
1010
+ return Vector3D(self)
1011
+
1012
+ @property
1013
+ def view(self):
1014
+ """`Cartesian3DView`: Viewport, axes orientation and limits adjustments.
1015
+
1016
+ Example usage::
1017
+
1018
+ >>> plot.view.fit()
1019
+ """
1020
+ return view.Cartesian3DView(self)
1021
+
1022
+ @property
1023
+ def use_lighting_effect(self):
1024
+ """`bool`: Enable lighting effect for all objects within this plot.
1025
+
1026
+ Example usage::
1027
+
1028
+ >>> frame.plot().use_lighting_effect = True
1029
+ """
1030
+ return self._get_style(bool, sv.USELIGHTINGEFFECT)
1031
+
1032
+ @use_lighting_effect.setter
1033
+ def use_lighting_effect(self, value):
1034
+ self._set_style(bool(value), sv.USELIGHTINGEFFECT)
1035
+
1036
+ @property
1037
+ def use_translucency(self):
1038
+ """`bool`: Enable translucent effect for all objects within this plot.
1039
+
1040
+ Example usage::
1041
+
1042
+ >>> frame.plot().use_translucency = True
1043
+ """
1044
+ return self._get_style(bool, sv.USETRANSLUCENCY)
1045
+
1046
+ @use_translucency.setter
1047
+ def use_translucency(self, show):
1048
+ self._set_style(bool(show), sv.USETRANSLUCENCY)
1049
+
1050
+ @property
1051
+ def light_source(self):
1052
+ """`LightSource`: Control the direction and effects of lighting.
1053
+
1054
+ Example usage::
1055
+
1056
+ >>> plot.light_source.intensity = 70.0
1057
+ """
1058
+ return effects.LightSource(self)
1059
+
1060
+ @property
1061
+ def value_blanking(self):
1062
+ """`ValueBlanking`: Mask off cells by value.
1063
+
1064
+ Example usage::
1065
+
1066
+ >>> plot.value_blanking.constraint(0).comparison_value = 3.14
1067
+ >>> plot.value_blanking.constraint(0).active = True
1068
+ """
1069
+ return blanking.ValueBlankingCartesian3D(self)
1070
+
1071
+ @property
1072
+ def line_lift_fraction(self):
1073
+ """`float`: Lift lines above plot by percentage distance to the eye.
1074
+
1075
+ Example usage::
1076
+
1077
+ >>> plot.line_lift_fraction = 0.6
1078
+ """
1079
+ style = session.Style(sv.GLOBALTHREED, **self._kw)
1080
+ return style._get_style(float, sv.LINELIFTFRACTION)
1081
+
1082
+ @line_lift_fraction.setter
1083
+ def line_lift_fraction(self, value):
1084
+ style = session.Style(sv.GLOBALTHREED, **self._kw)
1085
+ style._set_style(float(value), sv.LINELIFTFRACTION)
1086
+
1087
+ @property
1088
+ def near_plane_fraction(self):
1089
+ """`float`: position of the "near plane".
1090
+
1091
+ In a 3D plot, the "near plane" acts as a windshield. Anything in front
1092
+ of this plane does not display. Example usage::
1093
+
1094
+ >>> plot.near_plane_fraction = 0.1
1095
+ """
1096
+ style = session.Style(sv.GLOBALTHREED, **self._kw)
1097
+ return style._get_style(float, sv.NEARPLANEFRACTION)
1098
+
1099
+ @near_plane_fraction.setter
1100
+ def near_plane_fraction(self, value):
1101
+ style = session.Style(sv.GLOBALTHREED, **self._kw)
1102
+ style._set_style(float(value), sv.NEARPLANEFRACTION)
1103
+
1104
+ @property
1105
+ def perform_extra_sorting(self):
1106
+ """`bool`: Use a more robust depth sorting algorithm for display.
1107
+
1108
+ When printing 3D plots in a vector graphics format, Tecplot 360 must
1109
+ sort the objects so that it can draw those farthest from the screen
1110
+ first and those closest to the screen last. By default, Tecplot 360
1111
+ uses a quick sorting algorithm. This is not always accurate and does
1112
+ not detect problems such as intersecting objects. When
1113
+ ``perform_extra_sorting`` set to `True`, Tecplot 360 uses a slower,
1114
+ more accurate approach that detects and resolves such problems. Example
1115
+ usage::
1116
+
1117
+ >>> plot.perform_extra_sorting = True
1118
+ """
1119
+ style = session.Style(sv.GLOBALTHREED, **self._kw)
1120
+ return style._get_style(bool, sv.PERFORMEXTRA3DSORTING)
1121
+
1122
+ @perform_extra_sorting.setter
1123
+ def perform_extra_sorting(self, value):
1124
+ style = session.Style(sv.GLOBALTHREED, **self._kw)
1125
+ style._set_style(bool(value), sv.PERFORMEXTRA3DSORTING)
1126
+
1127
+ @property
1128
+ def symbol_lift_fraction(self):
1129
+ """`float`: Lift symbols above plot by percentage distance to the eye.
1130
+
1131
+ Example usage::
1132
+
1133
+ >>> plot.symbol_lift_fraction = 0.6
1134
+ """
1135
+ style = session.Style(sv.GLOBALTHREED, **self._kw)
1136
+ return style._get_style(float, sv.SYMBOLLIFTFRACTION)
1137
+
1138
+ @symbol_lift_fraction.setter
1139
+ def symbol_lift_fraction(self, value):
1140
+ style = session.Style(sv.GLOBALTHREED, **self._kw)
1141
+ style._set_style(float(value), sv.SYMBOLLIFTFRACTION)
1142
+
1143
+ @property
1144
+ def vector_lift_fraction(self):
1145
+ """`float`: Lift vectors above plot by percentage distance to the eye.
1146
+
1147
+ Example usage::
1148
+
1149
+ >>> plot.vector_lift_fraction = 0.6
1150
+ """
1151
+ style = session.Style(sv.GLOBALTHREED, **self._kw)
1152
+ return style._get_style(float, sv.VECTORLIFTFRACTION)
1153
+
1154
+ @vector_lift_fraction.setter
1155
+ def vector_lift_fraction(self, value):
1156
+ style = session.Style(sv.GLOBALTHREED, **self._kw)
1157
+ style._set_style(float(value), sv.VECTORLIFTFRACTION)
1158
+
1159
+ @property
1160
+ def linking_between_frames(self):
1161
+ """`Cartesian3DPlotLinkingBetweenFrames`: Style linking between frames.
1162
+
1163
+ Example usage::
1164
+
1165
+ >>> plot.linking_between_frames.group = 1
1166
+ >>> plot.linking_between_frames.link_solution_time = True
1167
+ """
1168
+ return linking.Cartesian3DPlotLinkingBetweenFrames(self.frame)
1169
+
1170
+
1171
+ class LinePlot(Plot):
1172
+ """Plot with line data and associated style through linemaps.
1173
+
1174
+ .. code-block:: python
1175
+
1176
+ from os import path
1177
+ import tecplot as tp
1178
+ from tecplot.constant import PlotType, Color, LinePattern
1179
+
1180
+ examples_dir = tp.session.tecplot_examples_directory()
1181
+ infile = path.join(examples_dir, 'SimpleData', 'Rainfall.dat')
1182
+ dataset = tp.data.load_tecplot(infile)
1183
+
1184
+ frame = tp.active_frame()
1185
+ frame.plot_type = PlotType.XYLine
1186
+ plot = frame.plot()
1187
+ plot.show_symbols = True
1188
+
1189
+ # save image to file
1190
+ tp.export.save_png('plot_line.png', 600, supersample=3)
1191
+
1192
+ .. figure:: /_static/images/plot_line.png
1193
+ :width: 300px
1194
+ :figwidth: 300px
1195
+ """
1196
+
1197
+ def __init__(self, frame):
1198
+ super().__init__(frame, sv.LINEPLOTLAYERS)
1199
+
1200
+ @tecutil.lock()
1201
+ def delete_linemaps(self, *linemaps):
1202
+ r"""Clear all linemaps within this plot.
1203
+
1204
+ Parameters:
1205
+ \*linemaps (:ref:`Linemap`, `int` or `str`):
1206
+ One or more of the following: :ref:`Linemap` objects, linemap
1207
+ indices (zero-based) or linemap names. If none are given, all
1208
+ linemaps will be deleted.
1209
+
1210
+ Example usage::
1211
+
1212
+ >>> plot.delete_linemaps()
1213
+ >>> print(plot.num_linemaps)
1214
+ 0
1215
+ """
1216
+ if not linemaps:
1217
+ return _tecutil.LineMapDelete(None)
1218
+ with tecutil.IndexSet() as indices:
1219
+ for lmap in tecutil.flatten_args(*linemaps):
1220
+ try:
1221
+ # try as a Linemap object
1222
+ indices.append(lmap.index)
1223
+ except (AttributeError, TypeError):
1224
+ try:
1225
+ # try as a linemap index
1226
+ indices.append(lmap)
1227
+ except TypeError:
1228
+ # assume name pattern
1229
+ for submap in self.linemaps(lmap):
1230
+ indices.append(submap.index)
1231
+ return _tecutil.LineMapDelete(indices)
1232
+
1233
+ @property
1234
+ def num_linemaps(self):
1235
+ """`int`: Number of linemaps held by this plot.
1236
+
1237
+ Example usage::
1238
+
1239
+ >>> print(plot.num_linemaps)
1240
+ 3
1241
+ """
1242
+ return _tecutil.LineMapGetCountForFrame(self.frame.uid)
1243
+
1244
+ def _linemap_indices_by_name(self, pattern):
1245
+ pattern_type = getattr(re, 'Pattern', getattr(re, '_pattern_type', None))
1246
+ if not isinstance(pattern, pattern_type):
1247
+ regex = re.compile(fnmatch.translate(pattern), re.IGNORECASE)
1248
+ else:
1249
+ regex = pattern
1250
+
1251
+ indices = set()
1252
+ with self.frame.activated():
1253
+ found = False
1254
+ for i in range(self.num_linemaps):
1255
+ try:
1256
+ _, name = _tecutil.LineMapGetName(i + 1)
1257
+ name = name or ''
1258
+ except (AttributeError, TecplotSystemError):
1259
+ name = ''
1260
+ if regex.match(name):
1261
+ found = True
1262
+ indices.add(i)
1263
+ if __debug__:
1264
+ if (
1265
+ not found and
1266
+ isinstance(pattern, str) and
1267
+ any(c in pattern for c in '*?[]')
1268
+ ):
1269
+ msg = 'no linemaps found matching: "{}"'.format(pattern)
1270
+ warning = TecplotPatternMatchWarning(pattern, msg)
1271
+ warnings.warn(warning)
1272
+ return indices
1273
+
1274
+ def _linemap_indices(self, *keys):
1275
+ """
1276
+ convert keys to a set of indices where keys are:
1277
+ * int: get one linemap index (converting negative values)
1278
+ * regex pattern: match by name
1279
+ * glob-style string: match by name
1280
+ if no keys are given, get all linemaps indices
1281
+ """
1282
+ indices = set()
1283
+ if keys:
1284
+ for key in keys:
1285
+ if isinstance(key, int):
1286
+ index = key + self.num_linemaps if key < 0 else key
1287
+ if index >= self.num_linemaps:
1288
+ msg = 'linemap index out of range: ' + str(index)
1289
+ raise TecplotIndexError(msg)
1290
+ indices.add(index)
1291
+ else:
1292
+ indices |= self._linemap_indices_by_name(key)
1293
+ else:
1294
+ indices |= set(range(self.num_linemaps))
1295
+ return indices
1296
+
1297
+ @tecutil.lock()
1298
+ def _add_linemap(self, name, zone, show=True):
1299
+ with self.frame.activated():
1300
+ new_linemap_index = self.num_linemaps
1301
+ if not _tecutil.LineMapCreate():
1302
+ raise TecplotSystemError()
1303
+ linemap = self.linemap(new_linemap_index)
1304
+ if name is not None:
1305
+ linemap.name = name
1306
+ if zone is not None:
1307
+ linemap.zone_index = getattr(zone, 'index', zone)
1308
+ if show is not None:
1309
+ linemap.show = show
1310
+ return linemap
1311
+
1312
+ @property
1313
+ def legend(self):
1314
+ """`LineLegend`: Line plot legend style and placement control.
1315
+
1316
+ Example usage::
1317
+
1318
+ >>> plot.legend.show = True
1319
+ """
1320
+ return legend.LineLegend(self)
1321
+
1322
+ @property
1323
+ def active_linemap_indices(self):
1324
+ """`set` of `integers <int>`: `set` of all active linemaps by index.
1325
+
1326
+ Numbers are zero-based indices to the linemaps::
1327
+
1328
+ >>> active_indices = plot.active_linemap_indices
1329
+ >>> active_lmaps = [plot.linemap(i) for i in active_indices]
1330
+ """
1331
+ return session.get_style(set, sv.ACTIVELINEMAPS,
1332
+ uniqueid=self.frame.uid)
1333
+
1334
+ @property
1335
+ def show_lines(self):
1336
+ """`bool`: Enable lines for this plot.
1337
+
1338
+ Example usage::
1339
+
1340
+ >>> plot.show_lines = True
1341
+ """
1342
+ return self._get_style(bool, sv.SHOWLINES)
1343
+
1344
+ @show_lines.setter
1345
+ def show_lines(self, value):
1346
+ self._set_style(bool(value), sv.SHOWLINES)
1347
+
1348
+ @property
1349
+ def show_symbols(self):
1350
+ """`bool`: Enable symbols at line vertices for this plot.
1351
+
1352
+ Example usage::
1353
+
1354
+ >>> plot.show_symbols = True
1355
+ """
1356
+ return self._get_style(bool, sv.SHOWSYMBOLS)
1357
+
1358
+ @show_symbols.setter
1359
+ def show_symbols(self, value):
1360
+ self._set_style(bool(value), sv.SHOWSYMBOLS)
1361
+
1362
+ @property
1363
+ def value_blanking(self):
1364
+ """`ValueBlanking`: Mask off points by value.
1365
+
1366
+ Example usage::
1367
+
1368
+ >>> plot.value_blanking.constraint(0).comparison_value = 3.14
1369
+ >>> plot.value_blanking.constraint(0).active = True
1370
+ """
1371
+ return blanking.ValueBlanking(self)
1372
+
1373
+ @property
1374
+ def base_font(self):
1375
+ """`BaseFont`: Default typeface style control.
1376
+
1377
+ Example usage::
1378
+
1379
+ >>> plot.base_font.typeface = 'Times'
1380
+ """
1381
+ return text.BaseFont(sv.GLOBALLINEPLOT, **self._kw)
1382
+
1383
+ @property
1384
+ def data_labels(self):
1385
+ """`LinePlotDataLabels`: Node and cell labels.
1386
+
1387
+ This object controls displaying labels for every node and/or cell in
1388
+ the dataset. Example usage::
1389
+
1390
+ >>> plot.data_labels.show_node_labels = True
1391
+ >>> plot.data_labels.step_index = 10
1392
+ """
1393
+ return labels.LinePlotDataLabels(self)
1394
+
1395
+ @property
1396
+ def linking_within_frame(self):
1397
+ """`DataPlotLinkingWithinFrame`: Style linking within the frame.
1398
+
1399
+ Example usage::
1400
+
1401
+ >>> plot.linking_within_frame.link_gridline_style = True
1402
+ """
1403
+ return linking.DataPlotLinkingWithinFrame(self.frame)
1404
+
1405
+
1406
+ class XYLinePlot(LinePlot):
1407
+ """Cartesian plot with line data and associated style through linemaps.
1408
+
1409
+ .. code-block:: python
1410
+ :emphasize-lines: 10-14
1411
+
1412
+ from os import path
1413
+ import tecplot as tp
1414
+ from tecplot.constant import PlotType, FillMode
1415
+
1416
+ examples_dir = tp.session.tecplot_examples_directory()
1417
+ infile = path.join(examples_dir, 'SimpleData', 'SunSpots.plt')
1418
+ dataset = tp.data.load_tecplot(infile)
1419
+
1420
+ frame = tp.active_frame()
1421
+ plot = frame.plot(PlotType.XYLine)
1422
+ plot.activate()
1423
+ plot.show_symbols = True
1424
+ plot.linemap(0).symbols.fill_mode = FillMode.UseLineColor
1425
+ plot.linemap(0).symbols.size = 1
1426
+
1427
+ tp.export.save_png('plot_xyline.png', 600, supersample=3)
1428
+
1429
+ .. figure:: /_static/images/plot_xyline.png
1430
+ :width: 300px
1431
+ :figwidth: 300px
1432
+ """
1433
+
1434
+ def activate(self):
1435
+ """Make this the active plot type on the parent frame.
1436
+
1437
+ Example usage::
1438
+
1439
+ >>> from tecplot.constant import PlotType
1440
+ >>> plot = frame.plot(PlotType.XYLine)
1441
+ >>> plot.activate()
1442
+ """
1443
+ self.frame.plot_type = PlotType.XYLine
1444
+
1445
+ def linemaps(self, *keys):
1446
+ """`XYLinemapCollection` by index or name.
1447
+
1448
+ Parameters:
1449
+ keys (`int`, `str` or `re.Pattern <re.compile>`): Zero-based
1450
+ index, case-insensitive `glob-style pattern string
1451
+ <fnmatch.fnmatch>` or a compiled `regex pattern instance
1452
+ <re.compile>` used to match the linemaps by name. A negative
1453
+ index is interpreted as counting from the end of the available
1454
+ linemaps.
1455
+
1456
+ Example usage, adjusting the line thickness for all lines in the plot::
1457
+
1458
+ >>> plot.linemaps().line.line_thickness = 1.4
1459
+ """
1460
+ indices = self._linemap_indices(*keys)
1461
+ return linemap.XYLinemapCollection(self, *indices)
1462
+
1463
+ def linemap(self, pattern):
1464
+ """Returns a specific linemap within this plot.
1465
+
1466
+ Parameters:
1467
+ pattern (`int`, `str` or `re.Pattern <re.compile>`): Zero-based
1468
+ index, case-insensitive
1469
+ `glob-style pattern string <fnmatch.fnmatch>` or a compiled
1470
+ `regex pattern instance <re.compile>` used to match the
1471
+ linemaps by name. A negative index is interpreted as counting
1472
+ from the end of the available linemaps.
1473
+
1474
+ Returns:
1475
+ `XYLinemap` corresponding to *pattern* or `None` if *pattern* was
1476
+ passed in as a `str` or `regex pattern instance <re.compile>` and
1477
+ no matching linemap was found.
1478
+
1479
+ .. note::
1480
+
1481
+ Plots can contain linemaps with identical names and only the first
1482
+ match found is returned. This is not guaranteed to be deterministic
1483
+ and care should be taken to have only linemaps with unique names
1484
+ when this feature is used.
1485
+
1486
+ Example usage::
1487
+
1488
+ >>> plot.linemap(0).error_bar.show = True
1489
+ """
1490
+ try:
1491
+ return next(iter(self.linemaps(pattern)))
1492
+ except StopIteration:
1493
+ pass
1494
+
1495
+ @property
1496
+ def active_linemaps(self):
1497
+ """`XYLinemapCollection`: Active linemaps in this plot.
1498
+
1499
+ Example usage::
1500
+
1501
+ >>> plot.active_linemaps.show_symbols = True
1502
+ """
1503
+ indices = self.active_linemap_indices
1504
+ return linemap.XYLinemapCollection(self, *indices)
1505
+
1506
+ def add_linemap(self, name=None, zone=None, x=None, y=None, show=True):
1507
+ """Add a linemap using the specified zone and variables.
1508
+
1509
+ Parameters:
1510
+
1511
+ name (`str`): Name of the linemap which can be used for
1512
+ retrieving with `XYLinePlot.linemap`. If `None`, then the
1513
+ linemap will not have a name. Default: `None`.
1514
+ zone (`Zone <data_access>`): The data to be used when drawing this
1515
+ linemap. If `None`, then |Tecplot Engine| will select a zone.
1516
+ Default: `None`.
1517
+ x (`Variable`): The ``x`` variable which must be from the same
1518
+ `Dataset <data.Dataset>` as ``y`` and ``zone``. If `None`, then
1519
+ |Tecplot Engine| will select an x variable. Default: `None`.
1520
+ y (`Variable`): The ``y`` variable which must be from the same
1521
+ `Dataset <data.Dataset>` as ``x`` and ``zone``. If `None`, then
1522
+ |Tecplot Engine| will select a ``y`` variable. Default: `None`.
1523
+ show (`bool`, optional): Enable this linemap as soon as
1524
+ it's added. (default: `True`). If `None`, then |Tecplot Engine|
1525
+ will determine if the linemap should be enabled.
1526
+
1527
+ Returns:
1528
+ `XYLinemap`
1529
+
1530
+ Example usage::
1531
+
1532
+ >>> lmap = plot.add_linemap('Line 1', dataset.zone('Zone'),
1533
+ ... dataset.variable('X'),
1534
+ ... dataset.variable('Y'))
1535
+ >>> lmap.line.line_thickness = 0.8
1536
+ """
1537
+ lmap = self._add_linemap(name, zone, show)
1538
+ if x is not None:
1539
+ lmap.x_variable = x
1540
+ if y is not None:
1541
+ lmap.y_variable = y
1542
+ return lmap
1543
+
1544
+ @property
1545
+ def axes(self):
1546
+ """`XYLineAxes`: Axes style control for this plot.
1547
+
1548
+ Example usage::
1549
+
1550
+ >>> from tecplot.constant import PlotType, AxisMode
1551
+ >>> frame.plot_type = PlotType.XYLine
1552
+ >>> axes = frame.plot().axes
1553
+ >>> axes.axis_mode = AxisMode.XYDependent
1554
+ >>> axes.xy_ratio = 2
1555
+ """
1556
+ return XYLineAxes(self)
1557
+
1558
+ @property
1559
+ def show_bars(self):
1560
+ """`bool`: Enable bar chart drawing mode for this plot.
1561
+
1562
+ Example usage::
1563
+
1564
+ >>> plot.show_bars = True
1565
+ """
1566
+ return self._get_style(bool, sv.SHOWBARCHARTS)
1567
+
1568
+ @show_bars.setter
1569
+ def show_bars(self, value):
1570
+ self._set_style(bool(value), sv.SHOWBARCHARTS)
1571
+
1572
+ @property
1573
+ def show_error_bars(self):
1574
+ """`bool`: Enable error bars for this plot.
1575
+
1576
+ The variable to be used for error bars must be set first on at least
1577
+ one linemap within this plot::
1578
+
1579
+ >>> plot.linemap(0).error_bars.variable = dataset.variable('E')
1580
+ >>> plot.show_error_bars = True
1581
+ """
1582
+ return self._get_style(bool, sv.SHOWERRORBARS)
1583
+
1584
+ @show_error_bars.setter
1585
+ def show_error_bars(self, value):
1586
+ self._set_style(bool(value), sv.SHOWERRORBARS)
1587
+
1588
+ @property
1589
+ def view(self):
1590
+ """`XYLineView`: View control of the plot relative to the frame.
1591
+
1592
+ Example usage::
1593
+
1594
+ >>> plot.view.fit()
1595
+ """
1596
+ return view.XYLineView(self)
1597
+
1598
+ @property
1599
+ def linking_between_frames(self):
1600
+ """`XYLinePlotLinkingBetweenFrames`: Style linking between frames.
1601
+
1602
+ Example usage::
1603
+
1604
+ >>> plot.linking_between_frames.group = 1
1605
+ >>> plot.linking_between_frames.link_solution_time = True
1606
+ """
1607
+ return linking.XYLinePlotLinkingBetweenFrames(self.frame)
1608
+
1609
+
1610
+ class PolarLinePlot(LinePlot):
1611
+ """Polar plot with line data and associated style through linemaps.
1612
+
1613
+ .. code-block:: python
1614
+ :emphasize-lines: 16-22
1615
+
1616
+ import numpy as np
1617
+ import tecplot as tp
1618
+ from tecplot.constant import *
1619
+
1620
+ frame = tp.active_frame()
1621
+
1622
+ npoints = 300
1623
+ r = np.linspace(0, 2000, npoints)
1624
+ theta = np.linspace(0, 10, npoints)
1625
+
1626
+ dataset = frame.create_dataset('Data', ['R', 'Theta'])
1627
+ zone = dataset.add_ordered_zone('Zone', (300,))
1628
+ zone.values('R')[:] = r
1629
+ zone.values('Theta')[:] = theta
1630
+
1631
+ plot = frame.plot(PlotType.PolarLine)
1632
+ plot.activate()
1633
+ plot.axes.r_axis.max = r.max()
1634
+ plot.axes.theta_axis.mode = ThetaMode.Radians
1635
+ plot.delete_linemaps()
1636
+ lmap = plot.add_linemap('Linemap', zone, dataset.variable('R'),
1637
+ dataset.variable('Theta'))
1638
+ lmap.line.line_thickness = 0.8
1639
+ lmap.line.color = Color.Green
1640
+
1641
+ plot.view.fit()
1642
+
1643
+ tp.export.save_png('plot_polar.png', 600, supersample=3)
1644
+
1645
+ .. figure:: /_static/images/plot_polar.png
1646
+ :width: 300px
1647
+ :figwidth: 300px
1648
+ """
1649
+
1650
+ def activate(self):
1651
+ """Make this the active plot type on the parent frame.
1652
+
1653
+ Example usage::
1654
+
1655
+ >>> from tecplot.constant import PlotType
1656
+ >>> plot = frame.plot(PlotType.PolarLine)
1657
+ >>> plot.activate()
1658
+ """
1659
+ self.frame.plot_type = PlotType.PolarLine
1660
+
1661
+ @property
1662
+ def axes(self):
1663
+ """`PolarLineAxes`: Axes style control for this plot.
1664
+
1665
+ Example usage::
1666
+
1667
+ >>> from tecplot.constant import PlotType, ThetaMode
1668
+ >>> frame.plot_type = PlotType.PolarLine
1669
+ >>> axes = frame.plot().axes
1670
+ >>> axes.theta_mode = ThetaMode.Radians
1671
+ """
1672
+ return PolarLineAxes(self)
1673
+
1674
+ @property
1675
+ def view(self):
1676
+ """`PolarView`: View control of the plot relative to the frame.
1677
+
1678
+ Example usage::
1679
+
1680
+ >>> plot.view.fit()
1681
+ """
1682
+ return view.PolarView(self)
1683
+
1684
+ def add_linemap(self, name=None, zone=None, r=None, theta=None, show=True):
1685
+ """Add a linemap using the specified zone and variables.
1686
+
1687
+ Parameters:
1688
+ name (`str`): Name of the linemap which can be used for
1689
+ retrieving with `PolarLinePlot.linemap`. If `None`, then the
1690
+ linemap will not have a name. Default: `None`.
1691
+ zone (`Zone <data_access>`): The data to be used when drawing this
1692
+ linemap. If `None`, then |Tecplot Engine| will select a
1693
+ `Zone <data_access>`.
1694
+ Default: `None`.
1695
+ r (`Variable`): The ``r`` variable which must be from the same
1696
+ `Dataset <data.Dataset>` as ``theta`` and ``zone``. If `None`, then
1697
+ |Tecplot Engine| will select a variable. Default: `None`.
1698
+ theta (`Variable`): The ``theta`` variable which must be from the
1699
+ same `Dataset <data.Dataset>` as ``r`` and ``zone``. If `None`, then
1700
+ |Tecplot Engine| will select a variable. Default: `None`.
1701
+ show (`bool`, optional): Enable this linemap as soon as
1702
+ it's added. (default: `True`)
1703
+
1704
+ Returns:
1705
+ `PolarLinemap`
1706
+
1707
+ Example usage::
1708
+
1709
+ >>> lmap = plot.add_linemap('Line 1', dataset.zone('Zone'),
1710
+ ... dataset.variable('R'),
1711
+ ... dataset.variable('Theta'))
1712
+ >>> lmap.line.line_thickness = 0.8
1713
+ """
1714
+ lmap = self._add_linemap(name, zone, show)
1715
+ if r is not None:
1716
+ lmap.r_variable = r
1717
+ if theta is not None:
1718
+ lmap.theta_variable = theta
1719
+ return lmap
1720
+
1721
+ def linemaps(self, *keys):
1722
+ """`PolarLinemapCollection` by index or name.
1723
+
1724
+ Parameters:
1725
+ keys (`int`, `str` or `re.Pattern <re.compile>`): Zero-based
1726
+ index, case-insensitive `glob-style pattern string
1727
+ <fnmatch.fnmatch>` or a compiled `regex pattern instance
1728
+ <re.compile>` used to match the linemaps by name. A negative
1729
+ index is interpreted as counting from the end of the available
1730
+ linemaps.
1731
+
1732
+ Example usage, adjusting the line thickness for all lines in the plot::
1733
+
1734
+ >>> plot.linemaps().line.line_thickness = 1.4
1735
+ """
1736
+ indices = self._linemap_indices(*keys)
1737
+ return linemap.PolarLinemapCollection(self, *indices)
1738
+
1739
+ def linemap(self, pattern):
1740
+ """Returns a specific linemap within this plot.
1741
+
1742
+ Parameters:
1743
+ pattern (`int`, `str` or `re.Pattern <re.compile>`): Zero-based
1744
+ index, case-insensitive
1745
+ `glob-style pattern string <fnmatch.fnmatch>` or a compiled
1746
+ `regex pattern instance <re.compile>` used to match the
1747
+ linemaps by name. A negative index is interpreted as counting
1748
+ from the end of the available linemaps.
1749
+
1750
+ Returns:
1751
+ `PolarLinemap` corresponding to *pattern* or `None` if *pattern*
1752
+ was passed in as a `str` or `regex pattern instance <re.compile>`
1753
+ and no matching linemap was found.
1754
+
1755
+ .. note::
1756
+
1757
+ Plots can contain linemaps with identical names and only the first
1758
+ match found is returned. This is not guaranteed to be deterministic
1759
+ and care should be taken to have only linemaps with unique names
1760
+ when this feature is used.
1761
+
1762
+ Example usage::
1763
+
1764
+ >>> plot.linemap(0).error_bar.show = True
1765
+ """
1766
+ try:
1767
+ return next(iter(self.linemaps(pattern)))
1768
+ except StopIteration:
1769
+ pass
1770
+
1771
+ @property
1772
+ def active_linemaps(self):
1773
+ """`PolarLinemapCollection`: Active linemaps in this plot.
1774
+
1775
+ Example usage::
1776
+
1777
+ >>> plot.active_linemaps.show_symbols = True
1778
+ """
1779
+ indices = self.active_linemap_indices
1780
+ return linemap.PolarLinemapCollection(self, *indices)
1781
+
1782
+ @property
1783
+ def linking_between_frames(self):
1784
+ """`PolarPlotLinkingBetweenFrames`: Style linking between frames.
1785
+
1786
+ Example usage::
1787
+
1788
+ >>> plot.linking_between_frames.group = 1
1789
+ >>> plot.linking_between_frames.link_solution_time = True
1790
+ """
1791
+ return linking.PolarPlotLinkingBetweenFrames(self.frame)