1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
"""Core visualization operations."""
# Authors: Alexandre Gramfort <alexandre.gramfort@inria.fr>
# Eric Larson <larson.eric.d@gmail.com>
# Joan Massich <mailsik@gmail.com>
# Guillaume Favelier <guillaume.favelier@gmail.com>
#
# License: Simplified BSD
from contextlib import contextmanager
import importlib
import sys
from ._utils import _get_backend_based_on_env_and_defaults, VALID_3D_BACKENDS
from ...utils import logger
from ...utils.check import _check_option
try:
MNE_3D_BACKEND
MNE_3D_BACKEND_TEST_DATA
except NameError:
MNE_3D_BACKEND = _get_backend_based_on_env_and_defaults()
MNE_3D_BACKEND_TEST_DATA = None
logger.info('Using %s 3d backend.\n' % MNE_3D_BACKEND)
_fromlist = ('_Renderer', '_Projection', '_close_all')
_name_map = dict(mayavi='_pysurfer_mayavi', pyvista='_pyvista')
if MNE_3D_BACKEND in VALID_3D_BACKENDS:
# This is (hopefully) the equivalent to:
# from ._whatever_name import ...
_mod = importlib.__import__(
_name_map[MNE_3D_BACKEND], {'__name__': __name__},
level=1, fromlist=_fromlist)
for key in _fromlist:
locals()[key] = getattr(_mod, key)
def set_3d_backend(backend_name):
"""Set the backend for MNE.
The backend will be set as specified and operations will use
that backend.
Parameters
----------
backend_name : str
The 3d backend to select. See Notes for the capabilities of each
backend.
Notes
-----
This table shows the capabilities of each backend ("✓" for full support,
and "-" for partial support):
.. table::
:widths: auto
+--------------------------------------+--------+---------+
| 3D function: | mayavi | pyvista |
+======================================+========+=========+
| :func:`plot_source_estimates` | ✓ | |
+--------------------------------------+--------+---------+
| :func:`plot_alignment` | ✓ | ✓ |
+--------------------------------------+--------+---------+
| :func:`plot_sparse_source_estimates` | ✓ | ✓ |
+--------------------------------------+--------+---------+
| :func:`plot_evoked_field` | ✓ | ✓ |
+--------------------------------------+--------+---------+
| :func:`plot_sensors_connectivity` | ✓ | |
+--------------------------------------+--------+---------+
| :func:`snapshot_brain_montage` | ✓ | - |
+--------------------------------------+--------+---------+
+--------------------------------------+--------+---------+
| **3D feature:** |
+--------------------------------------+--------+---------+
| Large data | ✓ | ✓ |
+--------------------------------------+--------+---------+
| Opacity/transparency | ✓ | ✓ |
+--------------------------------------+--------+---------+
| Support geometric glyph | ✓ | ✓ |
+--------------------------------------+--------+---------+
| Jupyter notebook | ✓ | ✓ |
+--------------------------------------+--------+---------+
| Interactivity in Jupyter notebook | ✓ | ✓ |
+--------------------------------------+--------+---------+
| Smooth shading | ✓ | ✓ |
+--------------------------------------+--------+---------+
| Subplotting | ✓ | |
+--------------------------------------+--------+---------+
| Eye-dome lighting | | |
+--------------------------------------+--------+---------+
| Exports to movie/GIF | | |
+--------------------------------------+--------+---------+
"""
_check_option('backend_name', backend_name, VALID_3D_BACKENDS)
global MNE_3D_BACKEND
MNE_3D_BACKEND = backend_name
importlib.reload(sys.modules[__name__])
def get_3d_backend():
"""Return the backend currently used.
Returns
-------
backend_used : str
The 3d backend currently in use.
"""
return MNE_3D_BACKEND
@contextmanager
def use_3d_backend(backend_name):
"""Create a viz context.
Parameters
----------
backend_name : str
The 3d backend to use in the context.
"""
old_backend = get_3d_backend()
set_3d_backend(backend_name)
try:
yield
finally:
set_3d_backend(old_backend)
@contextmanager
def _use_test_3d_backend(backend_name):
"""Create a testing viz context.
Parameters
----------
backend_name : str
The 3d backend to use in the context.
"""
with use_3d_backend(backend_name):
global MNE_3D_BACKEND_TEST_DATA
if backend_name == 'pyvista':
MNE_3D_BACKEND_TEST_DATA = True
yield
def set_3d_view(figure, azimuth=None, elevation=None,
focalpoint=None, distance=None):
"""Configure the view of the given scene.
Parameters
----------
figure:
The scene which is modified.
azimuth: float
The azimuthal angle of the view.
elevation: float
The zenith angle of the view.
focalpoint: tuple, shape (3,)
The focal point of the view: (x, y, z).
distance: float
The distance to the focal point.
"""
_mod._set_3d_view(figure=figure, azimuth=azimuth,
elevation=elevation, focalpoint=focalpoint,
distance=distance)
def set_3d_title(figure, title, size=40):
"""Configure the title of the given scene.
Parameters
----------
figure:
The scene which is modified.
title:
The title of the scene.
size: int
The size of the title.
"""
_mod._set_3d_title(figure=figure, title=title, size=size)
def create_3d_figure(size, bgcolor=(0, 0, 0)):
"""Return an empty figure based on the current 3d backend.
Parameters
----------
size: tuple
The dimensions of the 3d figure (width, height).
bgcolor: tuple
The color of the background.
Returns
-------
figure:
The requested empty scene.
"""
renderer = _mod._Renderer(size=size, bgcolor=bgcolor)
return renderer.scene()
|