|
6 | 6 |
|
7 | 7 | import os |
8 | 8 | import os.path as op |
| 9 | +import warnings |
9 | 10 | from contextlib import contextmanager, nullcontext |
10 | 11 |
|
11 | 12 | from ipyevents import Event |
|
112 | 113 |
|
113 | 114 | _JUPYTER_BACKEND = "trame" |
114 | 115 |
|
| 116 | + |
| 117 | +class _NotebookPlotter(Plotter): |
| 118 | + """PyVista ``Plotter`` for the notebook backend. |
| 119 | +
|
| 120 | + Validate the object returned by show, as PyVista silently falls back static PIL |
| 121 | + when the trame Jupyter backend cannot be loaded. |
| 122 | + """ |
| 123 | + |
| 124 | + def show(self, *args, **kwargs): |
| 125 | + with warnings.catch_warnings(record=True) as caught: |
| 126 | + warnings.simplefilter("always") |
| 127 | + viewer = super().show(*args, **kwargs) |
| 128 | + if not isinstance(viewer, Widget): |
| 129 | + reasons = "\n".join( |
| 130 | + f"- {w.message}" |
| 131 | + for w in caught |
| 132 | + if any(key in str(w.message) for key in ("backend", "trame", "static")) |
| 133 | + ) |
| 134 | + raise RuntimeError( |
| 135 | + f'The notebook 3D backend is not functional: the "{_JUPYTER_BACKEND}" ' |
| 136 | + "PyVista Jupyter backend returned a " |
| 137 | + f"{type(viewer).__module__}.{type(viewer).__qualname__} instead of an " |
| 138 | + "interactive widget. This usually means the installed trame packages " |
| 139 | + "(trame, trame-vtk, trame-vuetify, trame-pyvista) are missing or " |
| 140 | + "mutually incompatible." |
| 141 | + + (f"\n\nPyVista reported:\n{reasons}" if reasons else "") |
| 142 | + ) |
| 143 | + if kwargs["return_viewer"]: |
| 144 | + return viewer |
| 145 | + |
| 146 | + |
115 | 147 | # %% |
116 | 148 | # Widgets |
117 | 149 | # ------- |
|
0 commit comments