Exemplo n.º 1
0
def test_meg_inverse():
    """Test plotting of MEG inverse solution."""
    _set_backend()
    brain = Brain(*std_args)
    stc_fname = os.path.join(data_dir, 'meg_source_estimate-lh.stc')
    stc = io.read_stc(stc_fname)
    vertices = stc['vertices']
    colormap = 'hot'
    data = stc['data']
    data_full = (brain.geo['lh'].nn[vertices][..., np.newaxis] *
                 data[:, np.newaxis])
    time = np.linspace(stc['tmin'], stc['tmin'] + data.shape[1] * stc['tstep'],
                       data.shape[1], endpoint=False)

    def time_label(t):
        return 'time=%0.2f ms' % (1e3 * t)

    for use_data in (data, data_full):
        brain.add_data(use_data, colormap=colormap, vertices=vertices,
                       smoothing_steps=1, time=time, time_label=time_label)

    brain.scale_data_colormap(fmin=13, fmid=18, fmax=22, transparent=True)
    assert brain.data_dict['lh']['time_idx'] == 0

    brain.set_time(.1)
    assert brain.data_dict['lh']['time_idx'] == 2
    # viewer = TimeViewer(brain)

    # multiple data layers
    pytest.raises(ValueError, brain.add_data, data, vertices=vertices,
                  time=time[:-1])
    brain.add_data(data, colormap=colormap, vertices=vertices,
                   smoothing_steps=1, time=time, time_label=time_label,
                   initial_time=.09)
    assert brain.data_dict['lh']['time_idx'] == 1
    data_dicts = brain._data_dicts['lh']
    assert len(data_dicts) == 3
    assert data_dicts[0]['time_idx'] == 1
    assert data_dicts[1]['time_idx'] == 1

    # shift time in both layers
    brain.set_data_time_index(0)
    assert data_dicts[0]['time_idx'] == 0
    assert data_dicts[1]['time_idx'] == 0
    brain.set_data_smoothing_steps(2)

    # add second data-layer without time axis
    brain.add_data(data[:, 1], colormap=colormap, vertices=vertices,
                   smoothing_steps=2)
    brain.set_data_time_index(2)
    assert len(data_dicts) == 4

    # change surface
    brain.set_surf('white')

    # remove all layers
    brain.remove_data()
    assert brain._data_dicts['lh'] == []

    brain.close()
Exemplo n.º 2
0
def test_meg_inverse():
    """Test plotting of MEG inverse solution."""
    _set_backend()
    brain = Brain(*std_args)
    stc_fname = os.path.join(data_dir, 'meg_source_estimate-lh.stc')
    stc = io.read_stc(stc_fname)
    vertices = stc['vertices']
    colormap = 'hot'
    data = stc['data']
    data_full = (brain.geo['lh'].nn[vertices][..., np.newaxis] *
                 data[:, np.newaxis])
    time = np.linspace(stc['tmin'], stc['tmin'] + data.shape[1] * stc['tstep'],
                       data.shape[1], endpoint=False)

    def time_label(t):
        return 'time=%0.2f ms' % (1e3 * t)

    for use_data in (data, data_full):
        brain.add_data(use_data, colormap=colormap, vertices=vertices,
                       smoothing_steps=1, time=time, time_label=time_label)

    brain.scale_data_colormap(fmin=13, fmid=18, fmax=22, transparent=True)
    assert_equal(brain.data_dict['lh']['time_idx'], 0)

    brain.set_time(.1)
    assert_equal(brain.data_dict['lh']['time_idx'], 2)
    # viewer = TimeViewer(brain)

    # multiple data layers
    assert_raises(ValueError, brain.add_data, data, vertices=vertices,
                  time=time[:-1])
    brain.add_data(data, colormap=colormap, vertices=vertices,
                   smoothing_steps=1, time=time, time_label=time_label,
                   initial_time=.09)
    assert_equal(brain.data_dict['lh']['time_idx'], 1)
    data_dicts = brain._data_dicts['lh']
    assert_equal(len(data_dicts), 3)
    assert_equal(data_dicts[0]['time_idx'], 1)
    assert_equal(data_dicts[1]['time_idx'], 1)

    # shift time in both layers
    brain.set_data_time_index(0)
    assert_equal(data_dicts[0]['time_idx'], 0)
    assert_equal(data_dicts[1]['time_idx'], 0)
    brain.set_data_smoothing_steps(2)

    # add second data-layer without time axis
    brain.add_data(data[:, 1], colormap=colormap, vertices=vertices,
                   smoothing_steps=2)
    brain.set_data_time_index(2)
    assert_equal(len(data_dicts), 4)

    # change surface
    brain.set_surf('white')

    # remove all layers
    brain.remove_data()
    assert_equal(brain._data_dicts['lh'], [])

    brain.close()
Exemplo n.º 3
0
def test_meg_inverse():
    """Test plotting of MEG inverse solution
    """
    mlab.options.backend = 'test'
    brain = Brain(*std_args)
    stc_fname = os.path.join(data_dir, 'meg_source_estimate-lh.stc')
    stc = io.read_stc(stc_fname)
    data = stc['data']
    vertices = stc['vertices']
    time = np.linspace(stc['tmin'], stc['tmin'] + data.shape[1] * stc['tstep'],
                       data.shape[1], endpoint=False)
    colormap = 'hot'

    def time_label(t):
        return 'time=%0.2f ms' % (1e3 * t)

    brain.add_data(data, colormap=colormap, vertices=vertices,
                   smoothing_steps=10, time=time, time_label=time_label)
    brain.scale_data_colormap(fmin=13, fmid=18, fmax=22, transparent=True)
    assert_equal(brain.data_dict['lh']['time_idx'], 0)

    brain.set_time(.1)
    assert_equal(brain.data_dict['lh']['time_idx'], 2)
    # viewer = TimeViewer(brain)

    brain.add_data(data, colormap=colormap, vertices=vertices,
                   smoothing_steps=10, time=time, time_label=time_label,
                   initial_time=.09, remove_existing=True)
    assert_equal(brain.data_dict['lh']['time_idx'], 1)
    brain.close()
Exemplo n.º 4
0
def test_meg_inverse():
    """Test plotting of MEG inverse solution."""
    mlab.options.backend = 'test'
    brain = Brain(*std_args)
    stc_fname = os.path.join(data_dir, 'meg_source_estimate-lh.stc')
    stc = io.read_stc(stc_fname)
    data = stc['data']
    vertices = stc['vertices']
    time = np.linspace(stc['tmin'], stc['tmin'] + data.shape[1] * stc['tstep'],
                       data.shape[1], endpoint=False)
    colormap = 'hot'

    def time_label(t):
        return 'time=%0.2f ms' % (1e3 * t)

    brain.add_data(data, colormap=colormap, vertices=vertices,
                   smoothing_steps=10, time=time, time_label=time_label)
    brain.scale_data_colormap(fmin=13, fmid=18, fmax=22, transparent=True)
    assert_equal(brain.data_dict['lh']['time_idx'], 0)

    brain.set_time(.1)
    assert_equal(brain.data_dict['lh']['time_idx'], 2)
    # viewer = TimeViewer(brain)

    # multiple data layers
    assert_raises(ValueError, brain.add_data, data, vertices=vertices,
                  time=time[:-1])
    brain.add_data(data, colormap=colormap, vertices=vertices,
                   smoothing_steps=10, time=time, time_label=time_label,
                   initial_time=.09)
    assert_equal(brain.data_dict['lh']['time_idx'], 1)
    data_dicts = brain._data_dicts['lh']
    assert_equal(len(data_dicts), 2)
    assert_equal(data_dicts[0]['time_idx'], 1)
    assert_equal(data_dicts[1]['time_idx'], 1)

    # shift time in both layers
    brain.set_data_time_index(0)
    assert_equal(data_dicts[0]['time_idx'], 0)
    assert_equal(data_dicts[1]['time_idx'], 0)

    # remove all layers
    brain.remove_data()
    assert_equal(brain._data_dicts['lh'], [])

    brain.close()
Exemplo n.º 5
0
def test_meg_inverse():
    """Test plotting of MEG inverse solution."""
    mlab.options.backend = 'test'
    brain = Brain(*std_args)
    stc_fname = os.path.join(data_dir, 'meg_source_estimate-lh.stc')
    stc = io.read_stc(stc_fname)
    data = stc['data']
    vertices = stc['vertices']
    time = np.linspace(stc['tmin'],
                       stc['tmin'] + data.shape[1] * stc['tstep'],
                       data.shape[1],
                       endpoint=False)
    colormap = 'hot'

    def time_label(t):
        return 'time=%0.2f ms' % (1e3 * t)

    brain.add_data(data,
                   colormap=colormap,
                   vertices=vertices,
                   smoothing_steps=10,
                   time=time,
                   time_label=time_label)
    brain.scale_data_colormap(fmin=13, fmid=18, fmax=22, transparent=True)
    assert_equal(brain.data_dict['lh']['time_idx'], 0)

    brain.set_time(.1)
    assert_equal(brain.data_dict['lh']['time_idx'], 2)
    # viewer = TimeViewer(brain)

    brain.add_data(data,
                   colormap=colormap,
                   vertices=vertices,
                   smoothing_steps=10,
                   time=time,
                   time_label=time_label,
                   initial_time=.09,
                   remove_existing=True)
    assert_equal(brain.data_dict['lh']['time_idx'], 1)
    brain.close()
Exemplo n.º 6
0
def plot_source_estimates(stc,
                          subject=None,
                          surface='inflated',
                          hemi='lh',
                          colormap='auto',
                          time_label='auto',
                          smoothing_steps=10,
                          transparent=None,
                          alpha=1.0,
                          time_viewer=False,
                          config_opts=None,
                          subjects_dir=None,
                          figure=None,
                          views='lat',
                          colorbar=True,
                          clim='auto',
                          cortex="classic",
                          size=800,
                          background="black",
                          foreground="white",
                          initial_time=None,
                          time_unit=None):
    """Plot SourceEstimates with PySurfer

    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).

    Parameters
    ----------
    stc : SourceEstimates
        The source estimates 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
        The type of surface (inflated, white etc.).
    hemi : str, 'lh' | 'rh' | 'split' | 'both'
        The hemisphere to display.
    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
    transparent : bool | None
        If True, use a linear transparency between fmin and fmid.
        None will choose automatically based on colormap type.
    alpha : float
        Alpha value to apply globally to the overlay.
    time_viewer : bool
        Display time viewer GUI.
    config_opts : dict
        Deprecated parameter.
    subjects_dir : str
        The path to the freesurfer subjects reconstructions.
        It corresponds to Freesurfer environment variable SUBJECTS_DIR.
    figure : instance of mayavi.core.scene.Scene | 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.
    views : str | list
        View to use. See surfer.Brain().
    colorbar : bool
        If True, display colorbar on scene.
    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.
    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.
    background : matplotlib color
        Color of the background of the display window.
    foreground : matplotlib color
        Color of the foreground of the display window.
    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 (expected by PySurfer) or
        milliseconds. The current default is 'ms', but will change to 's'
        in MNE 0.14. To avoid a deprecation warning specify ``time_unit``
        explicitly.


    Returns
    -------
    brain : Brain
        A instance of surfer.viz.Brain from PySurfer.
    """
    import surfer
    from surfer import Brain, TimeViewer
    import mayavi

    # import here to avoid circular import problem
    from ..source_estimate import SourceEstimate

    surfer_version = LooseVersion(surfer.__version__)
    v06 = LooseVersion('0.6')
    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__)

    if time_unit is None:
        if initial_time is not None:
            warn(
                "The time_unit parameter default will change from 'ms' to "
                "'s' in MNE 0.14 and be removed in 0.15. To avoid this "
                "warning specify the parameter explicitly.",
                DeprecationWarning)
        time_unit = 'ms'
    elif time_unit not in ('s', 'ms'):
        raise ValueError("time_unit needs to be 's' or 'ms', got %r" %
                         (time_unit, ))

    if initial_time is not None and surfer_version > v06:
        kwargs = {'initial_time': initial_time}
        initial_time = None  # don't set it twice
    else:
        kwargs = {}

    if time_label == 'auto':
        if time_unit == 'ms':
            time_label = 'time=%0.2f ms'
        else:

            def time_label(t):
                return 'time=%0.2f ms' % (t * 1e3)

    if not isinstance(stc, SourceEstimate):
        raise ValueError('stc has to be a surface source estimate')

    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')

    # convert control points to locations in colormap
    ctrl_pts, colormap = _limits_to_control_points(clim, stc.data, colormap)

    # Construct cmap manually if 'mne' and get cmap bounds
    # and triage transparent argument
    if colormap in ('mne', 'mne_analyze'):
        colormap = mne_analyze_colormap(ctrl_pts)
        scale_pts = [-1 * ctrl_pts[-1], 0, ctrl_pts[-1]]
        transparent = False if transparent is None else transparent
    else:
        scale_pts = ctrl_pts
        transparent = True if transparent is None else transparent

    subjects_dir = get_subjects_dir(subjects_dir=subjects_dir,
                                    raise_error=True)
    subject = _check_subject(stc.subject, subject, True)
    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,
                      config_opts=config_opts)

    if time_unit == 's':
        times = stc.times
    else:  # time_unit == 'ms'
        times = 1e3 * stc.times

    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]
        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,
                           **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)
    if time_viewer:
        TimeViewer(brain)
    return brain
Exemplo n.º 7
0
                brain = Brain(nip, hemi, 'inflated', size=(800, 400), 
                              subjects_dir=data_mri_directory)

                # Add source time course
                brain.add_data(stc_data[hemi], colormap=colormap, 
                               vertices=stc_vertices[hemi], smoothing_steps=10, 
                               time=time_array, time_label=time_label, 
                               hemi=hemi, initial_time=0.)
                  
                # Scale the F-map                         
                brain.scale_data_colormap(fmin=fmin, fmid=fmid, fmax=fmax,
                                          transparent=True)

                # Add the image array to all images                
                for time in times:
                        brain.set_time(time)
                        fig_temp[hemi].append(brain.save_montage(filename=None, 
                                                                 orientation='h'))

                fig_temp[hemi] = np.concatenate(fig_temp[hemi], axis=0)
                brain.close()


            # Correct for different lengths
            min_len = min(len(fig_temp['lh']), len(fig_temp['rh']))
            fig_temp['lh'] = fig_temp['lh'][0:min_len, :, :]
            fig_temp['rh'] = fig_temp['rh'][0:min_len, :, :]
            
            # Collapse hemispheric images into one
            fig_array = np.concatenate([fig_temp['lh'], fig_temp['rh']], axis=1)
            
Exemplo n.º 8
0
def plot_source_estimates(stc, subject=None, surface='inflated', hemi='lh',
                          colormap='auto', time_label='auto',
                          smoothing_steps=10, transparent=None, alpha=1.0,
                          time_viewer=False, config_opts=None,
                          subjects_dir=None, figure=None, views='lat',
                          colorbar=True, clim='auto', cortex="classic",
                          size=800, background="black", foreground="white",
                          initial_time=None, time_unit=None):
    """Plot SourceEstimates with PySurfer

    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).

    Parameters
    ----------
    stc : SourceEstimates
        The source estimates 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
        The type of surface (inflated, white etc.).
    hemi : str, 'lh' | 'rh' | 'split' | 'both'
        The hemisphere to display.
    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
    transparent : bool | None
        If True, use a linear transparency between fmin and fmid.
        None will choose automatically based on colormap type.
    alpha : float
        Alpha value to apply globally to the overlay.
    time_viewer : bool
        Display time viewer GUI.
    config_opts : dict
        Deprecated parameter.
    subjects_dir : str
        The path to the freesurfer subjects reconstructions.
        It corresponds to Freesurfer environment variable SUBJECTS_DIR.
    figure : instance of mayavi.core.scene.Scene | 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.
    views : str | list
        View to use. See surfer.Brain().
    colorbar : bool
        If True, display colorbar on scene.
    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.
    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.
    background : matplotlib color
        Color of the background of the display window.
    foreground : matplotlib color
        Color of the foreground of the display window.
    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 (expected by PySurfer) or
        milliseconds. The current default is 'ms', but will change to 's'
        in MNE 0.14. To avoid a deprecation warning specify ``time_unit``
        explicitly.


    Returns
    -------
    brain : Brain
        A instance of surfer.viz.Brain from PySurfer.
    """
    import surfer
    from surfer import Brain, TimeViewer
    import mayavi

    # import here to avoid circular import problem
    from ..source_estimate import SourceEstimate

    surfer_version = LooseVersion(surfer.__version__)
    v06 = LooseVersion('0.6')
    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__)

    if initial_time is not None and surfer_version > v06:
        kwargs = {'initial_time': initial_time}
        initial_time = None  # don't set it twice
    else:
        kwargs = {}

    if time_unit is None:
        warn("The time_unit parameter default will change from 'ms' to 's' "
             "in MNE 0.14. To avoid this warning specify the parameter "
             "explicitly.", DeprecationWarning)
        time_unit = 'ms'
    elif time_unit not in ('s', 'ms'):
        raise ValueError("time_unit needs to be 's' or 'ms', got %r" %
                         (time_unit,))

    if time_label == 'auto':
        if time_unit == 'ms':
            time_label = 'time=%0.2f ms'
        else:
            def time_label(t):
                return 'time=%0.2f ms' % (t * 1e3)

    if not isinstance(stc, SourceEstimate):
        raise ValueError('stc has to be a surface source estimate')

    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')

    # convert control points to locations in colormap
    ctrl_pts, colormap = _limits_to_control_points(clim, stc.data, colormap)

    # Construct cmap manually if 'mne' and get cmap bounds
    # and triage transparent argument
    if colormap in ('mne', 'mne_analyze'):
        colormap = mne_analyze_colormap(ctrl_pts)
        scale_pts = [-1 * ctrl_pts[-1], 0, ctrl_pts[-1]]
        transparent = False if transparent is None else transparent
    else:
        scale_pts = ctrl_pts
        transparent = True if transparent is None else transparent

    subjects_dir = get_subjects_dir(subjects_dir=subjects_dir,
                                    raise_error=True)
    subject = _check_subject(stc.subject, subject, True)
    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, surface, True, title, cortex, size,
                      background, foreground, figure, subjects_dir, views,
                      config_opts=config_opts)

    if time_unit == 's':
        times = stc.times
    else:  # time_unit == 'ms'
        times = 1e3 * stc.times

    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]
        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, **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)
    if time_viewer:
        TimeViewer(brain)
    return brain