Skip to content

Commit 396d450

Browse files
committed
Removing pyvista dependency (#1066)
* Disabling '_get_sg_image_scraper' * lazy import of pyvista, and checks when vtk=true * Moving eplot to mapdl with the other Xplot functions * Making pyvista a lazy import in general plotter. * Making pyvista and pyiges optional in the report. * Avoiding passing extra general_plotter kwargs to mapdl._run. * Fixing unit tests * Improvements in the coverage tests. * Improving coverage * Fixing unit tests * Improving coverage
1 parent a351639 commit 396d450

File tree

6 files changed

+174
-93
lines changed

6 files changed

+174
-93
lines changed

src/ansys/mapdl/core/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@
1212
_LOCAL_PORTS = []
1313

1414
# Per contract with Sphinx-Gallery, this method must be available at top level
15-
from pyvista.utilities.sphinx_gallery import _get_sg_image_scraper
15+
try:
16+
from pyvista.utilities.sphinx_gallery import _get_sg_image_scraper
17+
18+
_HAS_PYVISTA = True
19+
except ModuleNotFoundError: # pragma: no cover
20+
LOG.debug("The module 'Pyvista' is not installed.")
21+
_HAS_PYVISTA = False
1622

1723
try:
1824
import importlib.metadata as importlib_metadata

src/ansys/mapdl/core/_commands/preproc/elements.py

Lines changed: 17 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
from typing import Optional, Union
2-
import warnings
32

43
from ansys.mapdl.core._commands.parse import parse_e
54
from ansys.mapdl.core.mapdl_types import MapdlFloat, MapdlInt
6-
from ansys.mapdl.core.plotting import general_plotter
75

86

97
class Elements:
@@ -1233,74 +1231,29 @@ def ensym(
12331231
"""
12341232
return self.run(f"ENSYM,{iinc},,{ninc},{iel1},{iel2},{ieinc}", **kwargs)
12351233

1236-
def eplot(self, show_node_numbering=False, vtk=None, **kwargs):
1234+
def eplot(self, **kwargs):
12371235
"""Plots the currently selected elements.
12381236
12391237
APDL Command: EPLOT
12401238
1241-
.. note::
1242-
PyMAPDL plotting commands with ``vtk=True`` ignore any
1243-
values set with the ``PNUM`` command.
1244-
1245-
Parameters
1246-
----------
1247-
vtk : bool, optional
1248-
Plot the currently selected elements using ``pyvista``.
1249-
Defaults to current ``use_vtk`` setting.
1250-
1251-
show_node_numbering : bool, optional
1252-
Plot the node numbers of surface nodes.
1253-
1254-
**kwargs
1255-
See ``help(ansys.mapdl.core.plotter.general_plotter)`` for more
1256-
keyword arguments related to visualizing using ``vtk``.
1257-
1258-
Examples
1259-
--------
1260-
>>> mapdl.clear()
1261-
>>> mapdl.prep7()
1262-
>>> mapdl.block(0, 1, 0, 1, 0, 1)
1263-
>>> mapdl.et(1, 186)
1264-
>>> mapdl.esize(0.1)
1265-
>>> mapdl.vmesh('ALL')
1266-
>>> mapdl.vgen(2, 'all')
1267-
>>> mapdl.eplot(show_edges=True, smooth_shading=True,
1268-
show_node_numbering=True)
1269-
1270-
Save a screenshot to disk without showing the plot
1271-
1272-
>>> mapdl.eplot(background='w', show_edges=True, smooth_shading=True,
1273-
window_size=[1920, 1080], savefig='screenshot.png',
1274-
off_screen=True)
1239+
Notes
1240+
------
1241+
Produces an element display of the selected elements. In full
1242+
graphics, only those elements faces with all of their corresponding
1243+
nodes selected are plotted. In PowerGraphics, all element faces of the selected
1244+
element set are plotted irrespective of the nodes selected. However,
1245+
for both full graphics and Power Graphics, adjacent or otherwise
1246+
duplicated faces of 3-D solid elements will not be displayed in an attempt
1247+
to eliminate plotting of interior facets. See the ``DSYS`` command for display
1248+
coordinate system issues.
1249+
This command will display curvature in midside node elements when PowerGraphics is activated
1250+
[``/GRAPHICS ,POWER``] and ``/EFACET,2`` or ``/EFACET,4`` are enabled. (To display
1251+
curvature, two facets per edge is recommended [``/EFACET,2``]). When you specify ``/EFACET,1``,
1252+
PowerGraphics does not display midside nodes. ``/EFACET`` has no effect on EPLOT for non-midside
1253+
node elements.
1254+
This command is valid in any processor.
12751255
12761256
"""
1277-
if vtk is None:
1278-
vtk = self._use_vtk
1279-
1280-
if vtk:
1281-
kwargs.setdefault("title", "MAPDL Element Plot")
1282-
if not self._mesh.n_elem:
1283-
warnings.warn("There are no elements to plot.")
1284-
return general_plotter([], [], [], **kwargs)
1285-
1286-
# TODO: Consider caching the surface
1287-
esurf = self.mesh._grid.linear_copy().extract_surface().clean()
1288-
kwargs.setdefault("show_edges", True)
1289-
1290-
# if show_node_numbering:
1291-
labels = []
1292-
if show_node_numbering:
1293-
labels = [{"points": esurf.points, "labels": esurf["ansys_node_num"]}]
1294-
1295-
return general_plotter(
1296-
[{"mesh": esurf, "style": kwargs.pop("style", "surface")}],
1297-
[],
1298-
labels,
1299-
**kwargs,
1300-
)
1301-
1302-
# otherwise, use MAPDL plotter
1303-
self._enable_interactive_plotting()
13041257
return self.run("EPLOT")
13051258

13061259
def eread(self, fname: str = "", ext: str = "", **kwargs) -> Optional[str]:

src/ansys/mapdl/core/mapdl.py

Lines changed: 118 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
from ansys.mapdl import core as pymapdl
2020
from ansys.mapdl.core import LOG as logger
21+
from ansys.mapdl.core import _HAS_PYVISTA
2122
from ansys.mapdl.core.commands import (
2223
CMD_BC_LISTING,
2324
CMD_LISTING,
@@ -149,7 +150,17 @@ def __init__(
149150
self._store_commands = False
150151
self._stored_commands = []
151152
self._response = None
152-
self._use_vtk = use_vtk
153+
154+
if _HAS_PYVISTA:
155+
self._use_vtk = use_vtk
156+
else: # pragma: no cover
157+
if use_vtk:
158+
raise ModuleNotFoundError(
159+
f"Using the keyword argument 'use_vtk' requires having Pyvista installed."
160+
)
161+
else:
162+
self._use_vtk = False
163+
153164
self._log_filehandler = None
154165
self._version = None # cached version
155166
self._local = local
@@ -967,12 +978,18 @@ def nplot(self, nnum="", vtk=None, **kwargs):
967978
>>> mapdl.nplot(vtk=False)
968979
969980
"""
970-
# lazy import here to avoid top level import
971-
import pyvista as pv
972-
973981
if vtk is None:
974982
vtk = self._use_vtk
975983

984+
if vtk is True:
985+
if _HAS_PYVISTA:
986+
# lazy import here to avoid top level import
987+
import pyvista as pv
988+
else: # pragma: no cover
989+
raise ModuleNotFoundError(
990+
f"Using the keyword argument 'vtk' requires having Pyvista installed."
991+
)
992+
976993
if "knum" in kwargs:
977994
raise ValueError("`knum` keyword deprecated. Please use `nnum` instead.")
978995

@@ -1000,6 +1017,81 @@ def nplot(self, nnum="", vtk=None, **kwargs):
10001017
self._enable_interactive_plotting()
10011018
return super().nplot(nnum, **kwargs)
10021019

1020+
def eplot(self, show_node_numbering=False, vtk=None, **kwargs):
1021+
"""Plots the currently selected elements.
1022+
1023+
APDL Command: EPLOT
1024+
1025+
.. note::
1026+
PyMAPDL plotting commands with ``vtk=True`` ignore any
1027+
values set with the ``PNUM`` command.
1028+
1029+
Parameters
1030+
----------
1031+
vtk : bool, optional
1032+
Plot the currently selected elements using ``pyvista``.
1033+
Defaults to current ``use_vtk`` setting.
1034+
1035+
show_node_numbering : bool, optional
1036+
Plot the node numbers of surface nodes.
1037+
1038+
**kwargs
1039+
See ``help(ansys.mapdl.core.plotter.general_plotter)`` for more
1040+
keyword arguments related to visualizing using ``vtk``.
1041+
1042+
Examples
1043+
--------
1044+
>>> mapdl.clear()
1045+
>>> mapdl.prep7()
1046+
>>> mapdl.block(0, 1, 0, 1, 0, 1)
1047+
>>> mapdl.et(1, 186)
1048+
>>> mapdl.esize(0.1)
1049+
>>> mapdl.vmesh('ALL')
1050+
>>> mapdl.vgen(2, 'all')
1051+
>>> mapdl.eplot(show_edges=True, smooth_shading=True,
1052+
show_node_numbering=True)
1053+
1054+
Save a screenshot to disk without showing the plot
1055+
1056+
>>> mapdl.eplot(background='w', show_edges=True, smooth_shading=True,
1057+
window_size=[1920, 1080], savefig='screenshot.png',
1058+
off_screen=True)
1059+
1060+
"""
1061+
if vtk is None:
1062+
vtk = self._use_vtk
1063+
elif vtk is True:
1064+
if not _HAS_PYVISTA: # pragma: no cover
1065+
raise ModuleNotFoundError(
1066+
f"Using the keyword argument 'vtk' requires having Pyvista installed."
1067+
)
1068+
1069+
if vtk:
1070+
kwargs.setdefault("title", "MAPDL Element Plot")
1071+
if not self._mesh.n_elem:
1072+
warnings.warn("There are no elements to plot.")
1073+
return general_plotter([], [], [], **kwargs)
1074+
1075+
# TODO: Consider caching the surface
1076+
esurf = self.mesh._grid.linear_copy().extract_surface().clean()
1077+
kwargs.setdefault("show_edges", True)
1078+
1079+
# if show_node_numbering:
1080+
labels = []
1081+
if show_node_numbering:
1082+
labels = [{"points": esurf.points, "labels": esurf["ansys_node_num"]}]
1083+
1084+
return general_plotter(
1085+
[{"mesh": esurf, "style": kwargs.pop("style", "surface")}],
1086+
[],
1087+
labels,
1088+
**kwargs,
1089+
)
1090+
1091+
# otherwise, use MAPDL plotter
1092+
self._enable_interactive_plotting()
1093+
return self.run("EPLOT")
1094+
10031095
def vplot(
10041096
self,
10051097
nv1="",
@@ -1064,6 +1156,11 @@ def vplot(
10641156
"""
10651157
if vtk is None:
10661158
vtk = self._use_vtk
1159+
elif vtk is True:
1160+
if not _HAS_PYVISTA: # pragma: no cover
1161+
raise ModuleNotFoundError(
1162+
f"Using the keyword argument 'vtk' requires having Pyvista installed."
1163+
)
10671164

10681165
if vtk:
10691166
kwargs.setdefault("title", "MAPDL Volume Plot")
@@ -1185,6 +1282,11 @@ def aplot(
11851282
"""
11861283
if vtk is None:
11871284
vtk = self._use_vtk
1285+
elif vtk is True:
1286+
if not _HAS_PYVISTA: # pragma: no cover
1287+
raise ModuleNotFoundError(
1288+
f"Using the keyword argument 'vtk' requires having Pyvista installed."
1289+
)
11881290

11891291
if vtk:
11901292
kwargs.setdefault("show_scalar_bar", False)
@@ -1380,6 +1482,11 @@ def lplot(
13801482
"""
13811483
if vtk is None:
13821484
vtk = self._use_vtk
1485+
elif vtk is True:
1486+
if not _HAS_PYVISTA: # pragma: no cover
1487+
raise ModuleNotFoundError(
1488+
f"Using the keyword argument 'vtk' requires having Pyvista installed."
1489+
)
13831490

13841491
if vtk:
13851492
kwargs.setdefault("show_scalar_bar", False)
@@ -1458,6 +1565,11 @@ def kplot(
14581565
"""
14591566
if vtk is None:
14601567
vtk = self._use_vtk
1568+
elif vtk is True:
1569+
if not _HAS_PYVISTA: # pragma: no cover
1570+
raise ModuleNotFoundError(
1571+
f"Using the keyword argument 'vtk' requires having Pyvista installed."
1572+
)
14611573

14621574
if vtk:
14631575
kwargs.setdefault("title", "MAPDL Keypoint Plot")
@@ -2342,7 +2454,8 @@ def run(self, command, write_to_log=True, mute=None, **kwargs) -> str:
23422454
# Edge case. `\title, 'par=1234' `
23432455
self._check_parameter_name(param_name)
23442456

2345-
text = self._run(command, mute=mute, **kwargs)
2457+
verbose = kwargs.get("verbose", False)
2458+
text = self._run(command, verbose=verbose, mute=mute)
23462459

23472460
if mute:
23482461
return

src/ansys/mapdl/core/misc.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,8 @@ def __init__(self, additional=None, ncol=3, text_width=80, sort=False, gpu=True)
6464
core = [
6565
"matplotlib",
6666
"numpy",
67-
"pyvista",
6867
"appdirs",
6968
"tqdm",
70-
"pyiges",
7169
"scipy",
7270
"grpc", # grpcio
7371
"ansys.api.mapdl.v0", # ansys-api-mapdl-v0
@@ -79,7 +77,7 @@ def __init__(self, additional=None, ncol=3, text_width=80, sort=False, gpu=True)
7977
core.extend(["pexpect"])
8078

8179
# Optional packages
82-
optional = ["matplotlib"]
80+
optional = ["matplotlib", "pyvista", "pyiges"]
8381
if sys.version_info[1] < 9:
8482
optional.append("ansys_corba")
8583

src/ansys/mapdl/core/plotting.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""Plotting helper for MAPDL using pyvista"""
22
import numpy as np
3-
import pyvista as pv
43

54
from ansys.mapdl.core.misc import unique_rows
65

@@ -212,6 +211,9 @@ def general_plotter(
212211
off_screen=True)
213212
214213
"""
214+
# Lazy import
215+
import pyvista as pv
216+
215217
if notebook:
216218
off_screen = True
217219

0 commit comments

Comments
 (0)