Source code for mvpure_py.viz.viz

import mne
import matplotlib.cm as cm
import matplotlib.pyplot as plt
import os
import numpy as np

from ..utils import (
    _check_hemi_param,
    get_pinv_RN_eigenvals
)
from ..utils._helper import split_kwargs


[docs] def plot_RN_eigenvalues( R: np.ndarray, N: np.ndarray, figsize: tuple = (12, 6), return_eigvals: bool = False, n_sources_threshold: float = 1.0, rank_threshold: float = 1.5, subject: str = None, **kwargs ) -> tuple[plt.Figure, np.ndarray] | plt.Figure: """ Plot eigenvalues of matrix :math:`RN^{-1}` where R is data covariance and N is noise covariance in descending order. Adding horizontal lines for the cut-off values: ``n_sources_to_localize`` and ``rank_threshold``. Parameters ---------- R : array-like Data covariance matrix N : array-like Noise covariance matrix figsize : tuple Size of the figure in the format (width, height) in inches. Default to (12,6). return_eigvals : bool Whether to rerun array with eigenvalues sorted in descending order. Default to False. n_sources_threshold : float Number of eigenvalues of the :math:`RN^{-1}` matrix below this threshold corresponds to the suggested number of sources to localize. Default to 1.0. For more details see Observation 1 in [1]_.. rank_threshold : float Number of eigenvalues of the :math:`RN^{-1}` matrix below this threshold corresponds to the suggested rank optimization parameter. Default to 1.5. For more details see Proposition 3 in [1]_. subject : str Subject name the analysis is performed for. Optional. References ---------- """ eigval = np.real( np.sort( np.linalg.eigvals(R @ np.linalg.pinv(N)) ) )[::-1] fig = plt.figure(figsize=figsize) plt.scatter(x=range(1, len(eigval) + 1), y=eigval, **kwargs) plt.hlines( y=n_sources_threshold, xmin=1, xmax=len(eigval) + 1, label=f"$\\mathrm{{RN}}^{{-1}}$=1", color="firebrick") plt.hlines( y=rank_threshold, xmin=1, xmax=len(eigval) + 1, label=f"$\\mathrm{{RN}}^{{-1}}$=3/2", color="darkseagreen") if subject is not None: plt.title(f"Subject: {subject} - $\\mathrm{{RN}}^{{-1}}$ eigenvalues") else: plt.title(f"$\\mathrm{{RN}}^{{-1}}$ eigenvalues") plt.grid(alpha=0.2) plt.legend() plt.show() if return_eigvals: return fig, eigval return fig
[docs] def plot_sources_with_activity( subject: str, stc: mne.SourceEstimate, hemi: str = "both", show_source_locations: bool = True, **kwargs ) -> mne.viz.Brain: """ Display ``mne.SourceEstimate.plot()`` with additional option to preview localized sources as black dots. This functionality helps when the user wants to view time series for individual sources, because user knows where to click. If ``show_source_locations`` is set to ``False``, it is equivalent to ``mne.SourceEstimate.plot()``. Parameters ---------- subject : str Subject name the analysis is performed for. Optional. stc : mne.SourceEstimate Source estimate obtained from signal reconstruction. hemi : str Hemisphere to show. Default to 'both' show_source_locations : bool Whether to preview positions of localized sources as black dots. Default to True. Returns ------- mne.viz.Brain : mne.viz.Brain object """ splitted_kwargs = split_kwargs(kwargs=kwargs, func_map={"stc_plot": mne.SourceEstimate.plot, "foci": mne.viz.Brain.add_foci}) _check_hemi_param(hemi) brain = stc.plot( subject=subject, hemi=hemi, **splitted_kwargs["stc_plot"] ) if show_source_locations: if hemi in ['both', 'lh'] and stc.lh_vertno.size != 0: brain.add_foci(stc.lh_vertno, coords_as_verts=True, hemi="lh", color='black', scale_factor=0.4, **splitted_kwargs["foci"]) if hemi in ['both', 'rh'] and stc.rh_vertno.size != 0: brain.add_foci(stc.rh_vertno, coords_as_verts=True, hemi="rh", color='black', scale_factor=0.4, **splitted_kwargs["foci"]) return brain
[docs] def plot_localized_sources( subject: str, lh_vertices: list = None, rh_vertices: list = None, hemi: str = "both", color="crimson", **kwargs) -> mne.viz.Brain: """ Display ``mne.viz.Brain`` with foci corresponding to positions of localized sources. Parameters ---------- subject : str Subject name the analysis is performed for. lh_vertices : list (optional) List of localized vertices in left hemisphere. rh_vertices : list (optional) List of localized vertices in right hemisphere. hemi : str (default: "both") Hemisphere to show. color : default ("crimson") Color to use for foci plotting. Can be anything matplotlib accepts. Returns ------- mne.viz.Brain : ``mne.viz.Brain`` object with foci added on localized sources coordinates. """ splitted_kwargs = split_kwargs(kwargs=kwargs, func_map={"brain": mne.viz.Brain, "foci": mne.viz.Brain.add_foci}) brain = mne.viz.Brain(subject=subject, surf="inflated", hemi=hemi, **splitted_kwargs["brain"]) if hemi in ["both", "lh"]: brain.add_foci( lh_vertices, coords_as_verts=True, hemi='lh', color=color, scale_factor=0.8, **splitted_kwargs["foci"]) if hemi in ["both", "rh"]: brain.add_foci( rh_vertices, coords_as_verts=True, hemi='rh', color=color, scale_factor=0.8, **splitted_kwargs["foci"]) return brain
def _assign_color_mapping(norm_power: float, cmap: str): cmap = cm.get_cmap(cmap) rgba = cmap(norm_power) rgb = tuple(int(255 * x) for x in rgba[:3]) return "#{:02X}{:02X}{:02X}".format(*rgb) def _save_brain_object(brain: mne.viz.Brain, output_path: str, output_name: str): """ Save mne.viz.Brain object to .html. Parameters ---------- brain : mne.viz.Brain mne.viz.Brain object to be saved to .html output_path : str Directory where 'brain' object should be saved. output_name : str Name of the .html file to be saved. """ if not os.path.exists(output_path): print(f"Output directory {output_path} does not exists. Creating...") os.makedirs(output_path) if len(output_name.split('.')) == 2 and output_name.split('.')[-1] != "html": raise ValueError(f"Only saving to .html file is possible. Got {output_name.split('.')[-1]}.") elif len(output_name.split('.')) == 1: output_name = f"{output_name}.html" # Get the pyvista plotter plotter = brain._renderer.plotter # Save as html plotter.export_html(os.path.join(output_path, output_name)) print(f"Saved to {os.path.join(output_path, output_name)}.")