Created
July 25, 2017 13:22
-
-
Save wmvanvliet/93f1cb4f8463371077687e16aacb1b25 to your computer and use it in GitHub Desktop.
One function to rule them all..
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def plot_source_estimates(stc, subject=None, surface=None, hemi='lh', | |
colormap='auto', time_label='auto', | |
smoothing_steps=10, transparent=None, | |
brain_alpha=None, alpha=None, vector_alpha=1., | |
scale_factor=None, time_viewer=False, | |
subjects_dir=None, figure=None, views='lat', | |
colorbar=True, clim='auto', cortex="classic", | |
size=800, background="black", foreground="white", | |
initial_time=None, time_unit='s', backend='auto', | |
spacing='oct6'): | |
"""Plot SourceEstimates with PySurfer or matplotlib. | |
Note: PySurfer currently needs the SUBJECTS_DIR environment variable, | |
which will automatically be set by this function. Plotting multiple | |
SourceEstimates with different values for subjects_dir will cause | |
PySurfer to use the wrong FreeSurfer surfaces when using methods of | |
the returned Brain object. It is therefore recommended to set the | |
SUBJECTS_DIR environment variable or always use the same value for | |
subjects_dir (within the same Python session). | |
By default this function uses Mayavi to plot the source estimates. If | |
Mayavi is not installed, the plotting is done with matplotlib (much slower, | |
decimated source space by default). | |
Parameters | |
---------- | |
stc : SourceEstimate | VectorSourceEstimate | |
The source estimate to plot. | |
subject : str | None | |
The subject name corresponding to FreeSurfer environment | |
variable SUBJECT. If None stc.subject will be used. If that | |
is None, the environment will be used. | |
surface : str | None | |
The type of surface (inflated, white etc.). By default, the inflated | |
surface is chosen for plotting SurfaceSourceEstimates. For | |
VectorSourceEstimates, the only valid option is the white matter | |
surface. | |
hemi : str, 'lh' | 'rh' | 'split' | 'both' | |
The hemisphere to display. Defaults to 'lh'. | |
colormap : str | np.ndarray of float, shape(n_colors, 3 | 4) | |
Name of colormap to use or a custom look up table. If array, must | |
be (n x 3) or (n x 4) array for with RGB or RGBA values between | |
0 and 255. If 'auto', either 'hot' or 'mne' will be chosen | |
based on whether 'lims' or 'pos_lims' are specified in `clim`. | |
time_label : str | callable | None | |
Format of the time label (a format string, a function that maps | |
floating point time values to strings, or None for no label). The | |
default is ``time=%0.2f ms``. | |
smoothing_steps : int | |
The amount of smoothing. Defaults to 10. | |
transparent : bool | None | |
If True, use a linear transparency between fmin and fmid. | |
None will choose automatically based on colormap type. Has no effect | |
with mpl backend. | |
brain_alpha : float | None | |
Alpha value to apply globally to the surface meshes. Defaults to 1. | |
when plotting SourceEstimates and 0.4 when plotting | |
VectorSourceEstimates. | |
alpha : float | None | |
Alpha value to apply globally to the overlay. Defaults to | |
``brain_alpha``. Has no effect with mpl backend. | |
vector_alpha : float | |
Alpha value to apply globally to the vector glyphs. Defaults to 1. | |
scale_factor : float | None | |
Scaling factor for vector glyphs. By default, an attempt is made to | |
automatically determine a sane value. | |
time_viewer : bool | |
Display time viewer GUI. Defaults to False. | |
subjects_dir : str | |
The path to the freesurfer subjects reconstructions. | |
By default this value is taken from the Freesurfer environment variable | |
SUBJECTS_DIR. | |
figure : instance of mayavi.core.scene.Scene | instance of matplotlib.figure.Figure | list | int | None | |
If None, a new figure will be created. If multiple views or a | |
split view is requested, this must be a list of the appropriate | |
length. If int is provided it will be used to identify the Mayavi | |
figure by it's id or create a new figure with the given id. If an | |
instance of matplotlib figure, mpl backend is used for plotting. | |
views : str | list | |
View to use. See surfer.Brain(). Supported views: ['lat', 'med', 'fos', | |
'cau', 'dor' 'ven', 'fro', 'par']. Using multiple views is not | |
supported for mpl backend. Defaults to a lateral ('lat') view. | |
colorbar : bool | |
If True, display colorbar on scene. Not available on mpl backend. | |
Defaults to True. | |
clim : str | dict | |
Colorbar properties specification. If 'auto', set clim automatically | |
based on data percentiles. If dict, should contain: | |
``kind`` : str | |
Flag to specify type of limits. 'value' or 'percent'. | |
``lims`` : list | np.ndarray | tuple of float, 3 elements | |
Note: Only use this if 'colormap' is not 'mne'. | |
Left, middle, and right bound for colormap. | |
``pos_lims`` : list | np.ndarray | tuple of float, 3 elements | |
Note: Only use this if 'colormap' is 'mne'. | |
Left, middle, and right bound for colormap. Positive values | |
will be mirrored directly across zero during colormap | |
construction to obtain negative control points. | |
cortex : str or tuple | |
Specifies how binarized curvature values are rendered. | |
Either the name of a preset PySurfer cortex colorscheme (one of | |
'classic', 'bone', 'low_contrast', or 'high_contrast'), or the name of | |
mayavi colormap, or a tuple with values (colormap, min, max, reverse) | |
to fully specify the curvature colors. Has no effect with mpl backend. | |
Defaults to 'classic'. | |
size : float or pair of floats | |
The size of the window, in pixels. can be one number to specify | |
a square window, or the (width, height) of a rectangular window. | |
Has no effect with mpl backend. | |
background : matplotlib color | |
Color of the background of the display window. Defaults to "black". | |
foreground : matplotlib color | |
Color of the foreground of the display window. Has no effect with mpl | |
backend. Defaults to "white". | |
initial_time : float | None | |
The time to display on the plot initially. ``None`` to display the | |
first time sample (default). | |
time_unit : 's' | 'ms' | |
Whether time is represented in seconds ("s", default) or | |
milliseconds ("ms"). | |
backend : 'auto' | 'mayavi' | 'matplotlib' | |
Which backend to use. If ``'auto'`` (default), tries to plot with | |
mayavi, but resorts to matplotlib if mayavi is not available. | |
.. versionadded:: 0.15.0 | |
spacing : str | |
The spacing to use for the source space. Can be ``'ico#'`` for a | |
recursively subdivided icosahedron, ``'oct#'`` for a recursively | |
subdivided octahedron, or ``'all'`` for all points. In general, you can | |
speed up the plotting by selecting a sparser source space. Has no | |
effect with mayavi backend. Defaults to 'oct6'. | |
.. versionadded:: 0.15.0 | |
Returns | |
------- | |
figure : surfer.viz.Brain | matplotlib.figure.Figure | |
An instance of surfer.viz.Brain from PySurfer or matplotlib figure. | |
""" # noqa: E501 | |
# import here to avoid circular import problem | |
from ..source_estimate import (_BaseSourceEstimate, SourceEstimate, | |
VectorSourceEstimate) | |
if not isinstance(stc, _BaseSourceEstimate): | |
raise ValueError('stc has to be a surface or vector source estimate') | |
subjects_dir = get_subjects_dir(subjects_dir=subjects_dir, | |
raise_error=True) | |
subject = _check_subject(stc.subject, subject, True) | |
if backend not in ['auto', 'matplotlib', 'mayavi']: | |
raise ValueError("backend must be 'auto', 'mayavi' or 'matplotlib'. " | |
"Got %s." % backend) | |
plot_mpl = backend == 'matplotlib' | |
if not plot_mpl: | |
try: | |
import mayavi | |
except ImportError: | |
if backend == 'auto' and isinstance(stc, SourceEstimate): | |
warn('Mayavi not found. Resorting to matplotlib 3d.') | |
plot_mpl = True | |
else: # 'mayavi' | |
raise | |
if plot_mpl: | |
if isinstance(stc, VectorSourceEstimate): | |
raise NotImplementedError( | |
'Plotting of VectorSourceEstimates using matplotlib is not ' | |
'supported.' | |
) | |
if surface is None: | |
surface = 'inflated' | |
return _plot_mpl_stc(stc, subject=subject, surface=surface, hemi=hemi, | |
colormap=colormap, time_label=time_label, | |
smoothing_steps=smoothing_steps, | |
subjects_dir=subjects_dir, views=views, clim=clim, | |
figure=figure, initial_time=initial_time, | |
time_unit=time_unit, background=background, | |
spacing=spacing, time_viewer=time_viewer) | |
import surfer | |
from surfer import Brain, TimeViewer | |
surfer_version = LooseVersion(surfer.__version__) | |
v06 = LooseVersion('0.6') | |
v07 = LooseVersion('0.7') | |
v08 = LooseVersion('0.8') | |
brain_kwargs = dict() | |
data_kwargs = dict() | |
if initial_time is not None and surfer_version > v06: | |
data_kwargs['initial_time'] = initial_time | |
initial_time = None # don't set it twice | |
time_label, times = _handle_time(time_label, time_unit, stc.times) | |
if hemi not in ['lh', 'rh', 'split', 'both']: | |
raise ValueError('hemi has to be either "lh", "rh", "split", ' | |
'or "both"') | |
# check `figure` parameter (This will be performed by PySurfer > 0.6) | |
if figure is not None: | |
if isinstance(figure, int): | |
# use figure with specified id | |
size_ = size if isinstance(size, (tuple, list)) else (size, size) | |
figure = [mayavi.mlab.figure(figure, size=size_)] | |
elif not isinstance(figure, (list, tuple)): | |
figure = [figure] | |
if not all(isinstance(f, mayavi.core.scene.Scene) for f in figure): | |
raise TypeError('figure must be a mayavi scene or list of scenes') | |
if isinstance(stc, SourceEstimate): | |
if surfer_version < v06: | |
raise ImportError("This function requires PySurfer 0.6 (you are " | |
"running version %s). You can update PySurfer " | |
"using:\n\n $ pip install -U pysurfer" % | |
surfer.__version__) | |
# convert control points to locations in colormap | |
scale_pts, colormap = _limits_to_control_points(clim, stc.data, | |
colormap) | |
if surface is None: | |
surface = 'inflated' | |
if brain_alpha is None: | |
brain_alpha = 1. | |
elif isinstance(stc, VectorSourceEstimate): | |
if surfer_version < v08: | |
raise ImportError("To plot vector source estimates, this function " | |
"requires PySurfer 0.8 (you are running version " | |
"%s). You can update PySurfer using:\n\n" | |
" $ pip install -U pysurfer" % | |
surfer.__version__) | |
# convert control points to locations in colormap | |
scale_pts, colormap = _limits_to_control_points( | |
clim, stc.magnitude().data, colormap | |
) | |
if surface is None: | |
surface = 'white' | |
elif surface != 'white': | |
raise ValueError("For plotting VectorSourceEstimates, the surface " | |
"parameter must be set to 'white'.") | |
data_kwargs['scale_factor'] = scale_factor | |
data_kwargs['vector_alpha'] = vector_alpha | |
if brain_alpha is None: | |
brain_alpha = 0.4 | |
else: | |
raise ValueError('stc has to be a surface or vector source estimate') | |
if surfer_version > v07: | |
brain_kwargs['alpha'] = brain_alpha | |
if alpha is None: | |
alpha = brain_alpha | |
if hemi in ['both', 'split']: | |
hemis = ['lh', 'rh'] | |
else: | |
hemis = [hemi] | |
title = subject if len(hemis) > 1 else '%s - %s' % (subject, hemis[0]) | |
with warnings.catch_warnings(record=True): # traits warnings | |
brain = Brain(subject, hemi=hemi, surf=surface, curv=True, | |
title=title, cortex=cortex, size=size, | |
background=background, foreground=foreground, | |
figure=figure, subjects_dir=subjects_dir, | |
views=views, **brain_kwargs) | |
_toggle_mlab_render(brain._figures, False) | |
for hemi in hemis: | |
hemi_idx = 0 if hemi == 'lh' else 1 | |
if hemi_idx == 0: | |
data = stc.data[:len(stc.vertices[0])] | |
else: | |
data = stc.data[len(stc.vertices[0]):] | |
vertices = stc.vertices[hemi_idx] | |
if len(data) > 0: | |
with warnings.catch_warnings(record=True): # traits warnings | |
brain.add_data(data, colormap=colormap, vertices=vertices, | |
smoothing_steps=smoothing_steps, time=times, | |
time_label=time_label, alpha=alpha, hemi=hemi, | |
colorbar=colorbar, **data_kwargs) | |
# scale colormap and set time (index) to display | |
brain.scale_data_colormap(fmin=scale_pts[0], fmid=scale_pts[1], | |
fmax=scale_pts[2], transparent=transparent) | |
if initial_time is not None: | |
brain.set_time(initial_time) | |
_toggle_mlab_render(brain._figures, True) | |
if time_viewer: | |
TimeViewer(brain) | |
return brain |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In my opinion, this version of the function is way too complicated. Too many branches, nooks and crannies, too many parameters that only work in certain cases (
SourceEstimate
vs.VectorSourceEstimate
, PySurfer v0.6 vs PySurfer v0.8, matplotlib backend vs PySurfer, etc).