|
15 | 15 | from ansys.dpf.core.check_version import meets_version
|
16 | 16 |
|
17 | 17 |
|
| 18 | +class _InternalPlotter: |
| 19 | + def __init__(self, **kwargs): |
| 20 | + try: |
| 21 | + import pyvista as pv |
| 22 | + except ModuleNotFoundError: |
| 23 | + raise ModuleNotFoundError( |
| 24 | + "To use plotting capabilities, please install pyvista " |
| 25 | + "with :\n pip install pyvista>=0.24.0" |
| 26 | + ) |
| 27 | + mesh = kwargs.pop("mesh", None) |
| 28 | + self._plotter = pv.Plotter(**kwargs) |
| 29 | + if mesh is not None: |
| 30 | + self._plotter.add_mesh(mesh.grid) |
| 31 | + |
| 32 | + def add_mesh(self, meshed_region, **kwargs): |
| 33 | + has_attribute_scalar_bar = False |
| 34 | + try: |
| 35 | + has_attribute_scalar_bar = hasattr(self._plotter, 'scalar_bar') |
| 36 | + except: |
| 37 | + has_attribute_scalar_bar = False |
| 38 | + |
| 39 | + if not has_attribute_scalar_bar: |
| 40 | + kwargs.setdefault("stitle", "Mesh") |
| 41 | + else: |
| 42 | + if self._plotter.scalar_bar.GetTitle() is None: |
| 43 | + kwargs.setdefault("stitle", "Mesh") |
| 44 | + kwargs.setdefault("show_edges", True) |
| 45 | + kwargs.setdefault("nan_color", "grey") |
| 46 | + self._plotter.add_mesh(meshed_region.grid, **kwargs) |
| 47 | + |
| 48 | + def add_field(self, field, meshed_region=None, **kwargs): |
| 49 | + name = field.name.split("_")[0] |
| 50 | + kwargs.setdefault("stitle", name) |
| 51 | + kwargs.setdefault("show_edges", True) |
| 52 | + kwargs.setdefault("nan_color", "grey") |
| 53 | + |
| 54 | + # get the meshed region location |
| 55 | + if meshed_region is None: |
| 56 | + meshed_region = field.meshed_region |
| 57 | + location = field.location |
| 58 | + if location == locations.nodal: |
| 59 | + mesh_location = meshed_region.nodes |
| 60 | + elif location == locations.elemental: |
| 61 | + mesh_location = meshed_region.elements |
| 62 | + else: |
| 63 | + raise ValueError( |
| 64 | + "Only elemental or nodal location are supported for plotting." |
| 65 | + ) |
| 66 | + component_count = field.component_count |
| 67 | + if component_count > 1: |
| 68 | + overall_data = np.full((len(mesh_location), component_count), np.nan) |
| 69 | + else: |
| 70 | + overall_data = np.full(len(mesh_location), np.nan) |
| 71 | + ind, mask = mesh_location.map_scoping(field.scoping) |
| 72 | + overall_data[ind] = field.data[mask] |
| 73 | + |
| 74 | + # plot |
| 75 | + self._plotter.add_mesh(meshed_region.grid, scalars=overall_data, **kwargs) |
| 76 | + |
| 77 | + def show_figure(self, **kwargs): |
| 78 | + background = kwargs.pop("background", None) |
| 79 | + if background is not None: |
| 80 | + self._plotter.set_background(background) |
| 81 | + |
| 82 | + # show result |
| 83 | + show_axes = kwargs.pop("show_axes", None) |
| 84 | + if show_axes: |
| 85 | + self._plotter.add_axes() |
| 86 | + return self._plotter.show() |
| 87 | + |
| 88 | + |
| 89 | +class DpfPlotter: |
| 90 | + def __init__(self, **kwargs): |
| 91 | + self._internal_plotter = _InternalPlotter(**kwargs) |
| 92 | + |
| 93 | + def add_mesh(self, meshed_region, **kwargs): |
| 94 | + """Add a mesh to plot. |
| 95 | +
|
| 96 | + Parameters |
| 97 | + ---------- |
| 98 | + meshed_region : MeshedRegion |
| 99 | + MeshedRegion to plot. |
| 100 | +
|
| 101 | + Examples |
| 102 | + -------- |
| 103 | + >>> from ansys.dpf import core as dpf |
| 104 | + >>> from ansys.dpf.core import examples |
| 105 | + >>> model = dpf.Model(examples.multishells_rst) |
| 106 | + >>> mesh = model.metadata.meshed_region |
| 107 | + >>> from ansys.dpf.core.plotter import DpfPlotter |
| 108 | + >>> pl = DpfPlotter() |
| 109 | + >>> pl.add_mesh(mesh) |
| 110 | +
|
| 111 | + """ |
| 112 | + self._internal_plotter.add_mesh(meshed_region=meshed_region, **kwargs) |
| 113 | + |
| 114 | + def add_field(self, field, meshed_region=None, **kwargs): |
| 115 | + """Add a field containing data to the plotter. |
| 116 | +
|
| 117 | + A meshed_region to plot on can be added. |
| 118 | + If no ``meshed_region`` is specified, the field |
| 119 | + support will be used. Ensure that the field |
| 120 | + support is a ``meshed_region``. |
| 121 | +
|
| 122 | + Parameters |
| 123 | + ---------- |
| 124 | + field : Field |
| 125 | + Field data to plot |
| 126 | + meshed_region : MeshedRegion, optional |
| 127 | + ``MeshedRegion`` to plot the field on. |
| 128 | +
|
| 129 | + Examples |
| 130 | + -------- |
| 131 | + >>> from ansys.dpf import core as dpf |
| 132 | + >>> from ansys.dpf.core import examples |
| 133 | + >>> model = dpf.Model(examples.multishells_rst) |
| 134 | + >>> mesh = model.metadata.meshed_region |
| 135 | + >>> field = model.results.displacement().outputs.fields_container()[0] |
| 136 | + >>> from ansys.dpf.core.plotter import DpfPlotter |
| 137 | + >>> pl = DpfPlotter() |
| 138 | + >>> pl.add_field(field, mesh) |
| 139 | +
|
| 140 | + """ |
| 141 | + self._internal_plotter.add_field(field=field, |
| 142 | + meshed_region=meshed_region, |
| 143 | + **kwargs) |
| 144 | + |
| 145 | + def show_figure(self, **kwargs): |
| 146 | + """Plot the figure built by the plotter object. |
| 147 | +
|
| 148 | + Examples |
| 149 | + -------- |
| 150 | + >>> from ansys.dpf import core as dpf |
| 151 | + >>> from ansys.dpf.core import examples |
| 152 | + >>> model = dpf.Model(examples.multishells_rst) |
| 153 | + >>> mesh = model.metadata.meshed_region |
| 154 | + >>> field = model.results.displacement().outputs.fields_container()[0] |
| 155 | + >>> from ansys.dpf.core.plotter import DpfPlotter |
| 156 | + >>> pl = DpfPlotter() |
| 157 | + >>> pl.add_field(field, mesh) |
| 158 | + >>> pl.show_figure() |
| 159 | +
|
| 160 | + """ |
| 161 | + self._internal_plotter.show_figure(**kwargs) |
| 162 | + |
18 | 163 | def plot_chart(fields_container):
|
19 | 164 | """Plot the minimum/maximum result values over time.
|
20 | 165 |
|
@@ -51,7 +196,8 @@ class Plotter:
|
51 | 196 |
|
52 | 197 | """
|
53 | 198 |
|
54 |
| - def __init__(self, mesh): |
| 199 | + def __init__(self, mesh, **kwargs): |
| 200 | + self._internal_plotter = _InternalPlotter(mesh=mesh, **kwargs) |
55 | 201 | self._mesh = mesh
|
56 | 202 |
|
57 | 203 | def plot_mesh(self, **kwargs):
|
@@ -140,6 +286,7 @@ def plot_contour(
|
140 | 286 | shell_layers=None,
|
141 | 287 | off_screen=None,
|
142 | 288 | show_axes=True,
|
| 289 | + meshed_region=None, |
143 | 290 | **kwargs
|
144 | 291 | ):
|
145 | 292 | """Plot the contour result on its mesh support.
|
@@ -202,7 +349,10 @@ def plot_contour(
|
202 | 349 | if label[DefinitionLabels.time] != first_time:
|
203 | 350 | raise dpf_errors.FieldContainerPlottingError
|
204 | 351 |
|
205 |
| - mesh = self._mesh |
| 352 | + if meshed_region is not None: |
| 353 | + mesh = meshed_region |
| 354 | + else: |
| 355 | + mesh = self._mesh |
206 | 356 |
|
207 | 357 | # get mesh scoping
|
208 | 358 | location = None
|
@@ -261,41 +411,39 @@ def plot_contour(
|
261 | 411 | cpos = kwargs.pop("cpos", None)
|
262 | 412 | return_cpos = kwargs.pop("return_cpos", None)
|
263 | 413 |
|
264 |
| - try: |
265 |
| - import pyvista as pv |
266 |
| - except ModuleNotFoundError: |
267 |
| - raise ModuleNotFoundError( |
268 |
| - "To use plotting capabilities, please install pyvista " |
269 |
| - "with :\n pip install pyvista>=0.24.0" |
270 |
| - ) |
271 |
| - plotter = pv.Plotter(notebook=notebook, off_screen=off_screen) |
| 414 | + # plotter = pv.Plotter(notebook=notebook, off_screen=off_screen) |
| 415 | + if notebook is not None: |
| 416 | + self._internal_plotter._plotter.notebook = notebook |
| 417 | + if off_screen is not None: |
| 418 | + self._internal_plotter._plotter.off_screen = off_screen |
272 | 419 |
|
273 | 420 | # add meshes
|
274 | 421 | kwargs.setdefault("show_edges", True)
|
275 | 422 | kwargs.setdefault("nan_color", "grey")
|
276 | 423 | kwargs.setdefault("stitle", name)
|
277 | 424 | text = kwargs.pop('text', None)
|
278 | 425 | if text is not None:
|
279 |
| - plotter.add_text(text, position='lower_edge') |
280 |
| - plotter.add_mesh(mesh.grid, scalars=overall_data, **kwargs) |
| 426 | + self._internal_plotter._plotter.add_text(text, position='lower_edge') |
| 427 | + self._internal_plotter._plotter.add_mesh(mesh.grid, scalars=overall_data, **kwargs) |
281 | 428 |
|
282 | 429 | if background is not None:
|
283 |
| - plotter.set_background(background) |
| 430 | + self._internal_plotter._plotter.set_background(background) |
284 | 431 |
|
285 | 432 | if cpos is not None:
|
286 |
| - plotter.camera_position = cpos |
| 433 | + self._internal_plotter._plotter.camera_position = cpos |
287 | 434 |
|
288 | 435 | # show result
|
289 | 436 | if show_axes:
|
290 |
| - plotter.add_axes() |
| 437 | + self._internal_plotter._plotter.add_axes() |
291 | 438 | if return_cpos is None:
|
292 |
| - return plotter.show() |
| 439 | + return self._internal_plotter._plotter.show() |
293 | 440 | else:
|
| 441 | + import pyvista as pv |
294 | 442 | pv_version = pv.__version__
|
295 | 443 | version_to_reach = '0.32.0'
|
296 | 444 | meet_ver = meets_version(pv_version, version_to_reach)
|
297 | 445 | if meet_ver:
|
298 |
| - return plotter.show(return_cpos=return_cpos) |
| 446 | + return self._internal_plotter._plotter.show(return_cpos=return_cpos) |
299 | 447 | else:
|
300 | 448 | txt = """To use the return_cpos option, please upgrade
|
301 | 449 | your pyvista module with a version higher than """
|
|
0 commit comments