neurocaps.analysis.CAP

class CAP(parcel_approach=None, groups=None)[source]

Co-Activation Patterns (CAPs) Class.

Initializes the CAPs (Co-activation Patterns) class.

Parameters:
  • parcel_approach (dict[str, dict[str, os.PathLike | list[str]]], dict[str, dict[str, str | int]], or os.PathLike, default=None) --

    The approach used to parcellate NifTI images. Similar to TimeseriesExtractor, "Schaefer" and "AAL" can be initialized here to create the appropriate parcel_approach that includes the sub-keys ("maps", "nodes", and "regions"), which are needed for several plotting functions in this class. This should be a nested dictionary with the first key being the parcellation name. Currently, only "Schaefer", "AAL", and "Custom" are supported. Recognized second level keys (sub-keys) are listed below:

    • For "Schaefer":

      • "n_rois": The number of ROIs (100, 200, 300, 400, 500, 600, 700, 800, 900, or 1000). Defaults to 400.

      • "yeo_networks": The number of Yeo networks (7 or 17). Defaults to 7.

      • "resolution_mm": The spatial resolution of the parcellation in millimeters (1 or 2). Defaults to 1.

    • For "AAL":

      • "version": The version of the AAL atlas used ("SPM5", "SPM8", "SPM12", or "3v2"). Defaults to "SPM12" if {"AAL": {}} is supplied.

    • For "Custom":

      • "maps": Directory path to the location of the parcellation file.

      • "nodes": A list of node names in the order of the label IDs in the parcellation.

      • "regions": The regions or networks in the parcellation.

    Note, if parcel_approach was initialized in TimeSeriesExtractor class, then this parameter can be set to self.parcel_approach. Refer to documentation from nilearn's datasets.fetch_atlas_schaefer_2018 and datasets.fetch_atlas_aal functions for more information about the "Schaefer" and "AAL" sub-keys. Also, refer to the "Note" section below for an explanation of the "Custom" sub-keys.

  • groups (dict[str, list[str]] or None, default=None) --

    A mapping of group names to unique subject IDs. If specified, then separate analyses are performed on groups (i.e., group-specific k-means models, group-specific visualization, etc). If None, then the analyses will be performed on all subjects and the default group name is "All Subjects". The structure should be as follows:

    {
        "GroupName1": ["1", "2", "3"],
        "GroupName2": ["4", "5", "6"],
    }
    

Properties

n_clusters: int or list[int]

An integer or list of integers (if cluster_selection_method is not None) that was used for sklearn.cluster.KMeans in self.get_caps().

groups: dict[str, list[str]] or None:

A mapping of groups names to unique subject IDs.

cluster_selection_method: str or None:

The cluster selection method used in self.get_caps() to identify the optimal number of clusters.

parcel_approach: dict[str, dict[str, os.PathLike | list[str]]]

A dictionary containing information about the parcellation. Can also be used as a setter, which accepts a dictionary or a dictionary saved as a pickle file. The structure is as follows:

# Structure of Schaefer
{
    "Schaefer":
    {
        "maps": "path/to/parcellation.nii.gz",
        "nodes": ["LH_Vis1", "LH_SomSot1", "RH_Vis1", "RH_SomSot1"],
        "regions": ["Vis", "SomSot"]
    }
}

# Structure of AAL
{
    "AAL":
    {
        "maps": "path/to/parcellation.nii.gz",
        "nodes": ["Precentral_L", "Precentral_R", "Frontal_Sup_L", "Frontal_Sup_R"],
        "regions": ["Precentral", "Frontal"]
    }
}

Refer to the example for "Custom" in the Note section below for the expected structure.

n_cores: int

Number of cores to use for multiprocessing with joblib. Is None until self.get_caps() is used and n_cores is specified.

runs: int or list[int]

The run IDs specified in self.get_caps().

caps: dict[str, dict[str, np.array]]

A dictionary mapping the cluster centroids, extracted from the k-means model, to each group after self.get_caps is used. The structure is as follows:

{
    "GroupName": {
        "CAP-1": np.array([...]), # Shape: 1 x ROIs
        "CAP-2": np.array([...]), # Shape: 1 x ROIs
    }

}
kmeans: dict[str, sklearn.cluster.KMeans]

A dictionary mapping group-specific sklearn.cluster.KMeans model to each group when self.get_caps() is used. If cluster_selection_method is used, the model stored in this property is the optimal k-means model. The structure is as follows:

{
    "GroupName": sklearn.cluster.KMeans,
}
cluster_scores: dict[str, Union[str, dict[str, float]]]

A dictionary mapping groups to the assessed cluster sizes and corresponding score of a specific cluster_selection_method available in self.get_caps(). The structure is as follows:

{
    "Cluster_Selection_Method": str,  # e.g., "elbow", "davies_bouldin", "silhouette", or "variance_ratio"
    "Scores": {
        "GroupName": {
            2: float,  # Score for 2 clusters
            3: float,  # Score for 3 clusters
            4: float,  # Score for 4 clusters
        },
    }
}

Added in version 0.19.0: inertia, silhouette, davies_bouldin, and variance_ratio consolidated into this property

variance_explained: dict[str, dict[float]]

A dictionary mapping groups to a float representing the total variance explained by their respective model stored in self.kmeans. The structure is as follows:

{
    "GroupName": float,
}

Added in version 0.18.8.

optimal_n_clusters: dict[str, dict[int]]

A dictionary mapping groups to their optimal cluster sizes if cluster_selection_method is not None in self.get_caps(). The structure is as follows:

{
    "GroupName": int,
}
standardize: bool

A boolean denoting whether the features of the concatenated timeseries data are standardized if standardization was requested in self.get_caps().

means: dict[str, np.array]

A dictionary mapping groups to their associated numpy array containing the means of each feature (ROI) if standardize is True in self.get_caps(). The structure is as follows:

{
    "GroupName": np.array([...]), # Shape: 1 x ROIs
}
stdev: dict[str, np.array]

A dictionary mapping groups to their associated numpy array containing the sample standard deviation of each feature (ROI) if standardize is True in self.get_caps(). The structure is as follows:

{
    "GroupName": np.array([...]), # Shape: 1 x ROIs
}
concatenated_timeseries: dict[str, np.array]

A dictionary mapping each group to their associated concatenated numpy array [(participants x TRs) x ROIs] when self.get_caps() is used. Note, if there are memory issues, delattr(self, "_concatenated_timeseries") (version < 0.18.10) or del self.concatenated_timeseries (version >= 0.18.10) can be used to delete property and have it only return None. The structure is as follows:

{
    "GroupName": np.array([...]), # Shape: (participants x TRs) x ROIs
}
region_caps: dict[str, np.array]

A dictionary mapping group to their CAPs and corresponding numpy array (1 x regions) containing the averaged value of each region or network if visual_scope set to "regions" in self.caps2plot(). The position of elements corresponds to "regions" in parcel_approach. The structure is as follows:

{
    "GroupName": {
        "CAP-1": np.array([...]), # Shape: 1 x regions
        "CAP-2": np.array([...]), # Shape: 1 x regions
    }

}
outer_products: dict[str, dict[str, np.array]]

A dictionary mapping group to their CAPs and corresponding numpy array (ROIs x ROIs) containing the outer product if plot_options set to "outer_product" self.caps2plot(). The structure is as follows:

{
    "GroupName": {
        "CAP-1": np.array([...]), # Shape: ROIs x ROIs
        "CAP-2": np.array([...]), # Shape: ROIs x ROIs
    }

}
subject_table: dict[str, str]

A dictionary generated when self.get_caps() is used. Operates as a lookup table that pairs each subject ID with the associated group. Also can be used as a setter. The structure is as follows.

{
    "Subject-ID": "GroupName",
    "Subject-ID": "GroupName",
}
cosine_similarity: :obj: dict[str, dict[list]]

A dictionary mapping each group to their CAPs and their associated "High Amplitude" and "Low Amplitude" list containing the cosine similarities. Each group contains a "Regions" key, consisting of a list of regions or networks. The position of the cosine similarities in the "High Amplitude" and "Low Amplitude" lists, corresponds to the region in the "Regions" list (Cosine similarity value in 0th index belongs to region in 0th index while the value in the 10th index belongs to the region in the 10th index).

{
    "GroupName": {
        "Regions": [...],
        "CAP-1": {"High Amplitude": [...], # Shape: 1 x Regions
                  "Low Amplitude": [...]   # Shape: 1 x Regions
                  }
        "CAP-2": {"High Amplitude": [...], # Shape: 1 x Regions
                  "Low Amplitude": [...]   # Shape: 1 x Regions
                  }
    }

}

Note

Default Group Name: If no groups were specified, the default group name will always be "All Subjects" to denote that the data of all subjects in the analysis were used to derive the CAPs. This is done to retain the same nesting structure for each property regardless if groups are specified.

Custom Parcellations: If using a "Custom" parcellation approach, ensure that the parcellation is lateralized (where each region/network has nodes in the left and right hemisphere). This is due to certain visualization functions assuming that each region consists of left and right hemisphere nodes. Additionally, certain visualization functions in this class also assume that the background label is 0. Therefore, do not add a background label in the "nodes" or "regions" keys.

The recognized sub-keys for the "Custom" parcellation approach includes:

  • "maps": Directory path containing the parcellation file in a supported format (e.g., .nii or .nii.gz for NifTI).

  • "nodes": A list of all node labels. The node labels should be arranged in ascending order based on their numerical IDs from the parcellation files. The node with the lowest numerical label in the parcellation file should occupy the 0th index in the list, regardless of its actual numerical value. For instance, if the numerical IDs are sequential, and the lowest, non-background numerical ID in the parcellation is "1" which corresponds to "left hemisphere visual cortex area" ("LH_Vis1"), then "LH_Vis1" should occupy the 0th element in this list. Even if the numerical IDs are non-sequential and the earliest non-background, numerical ID is "2000" (assuming "0" is the background), then the node label corresponding to "2000" should occupy the 0th element of this list.

    # Example of numerical label IDs and their organization in the "nodes" key
    "nodes": {
        "LH_Vis1",          # Corresponds to parcellation label 2000; lowest non-background numerical ID
        "LH_Vis2",          # Corresponds to parcellation label 2100; second lowest non-background numerical ID
        "LH_Hippocampus",   # Corresponds to parcellation label 2150; third lowest non-background numerical ID
        "RH_Vis1",          # Corresponds to parcellation label 2200; fourth lowest non-background numerical ID
        "RH_Vis2",          # Corresponds to parcellation label 2220; fifth lowest non-background numerical ID
        "RH_Hippocampus"    # Corresponds to parcellation label 2300; sixth lowest non-background numerical ID
    }
    
  • "regions": A dictionary defining major brain regions or networks. Each region should list node indices under "lh" (left hemisphere) and "rh" (right hemisphere) to specify the respective nodes. Both the "lh" and "rh" sub-keys should contain the indices of the nodes belonging to each region/hemisphere pair, as determined by the order/index in the "nodes" list. The naming of the sub-keys defining the major brain regions or networks have zero naming requirements and simply define the nodes belonging to the same name.

    # Example of the "regions" sub-keys
    "regions": {
        "Visual": {
            "lh": [0, 1], # Corresponds to "LH_Vis1" and "LH_Vis2"
            "rh": [3, 4]  # Corresponds to "RH_Vis1" and "RH_Vis2"
        },
        "Hippocampus": {
            "lh": [2], # Corresponds to "LH_Hippocampus"
            "rh": [5]  # Corresponds to "RH_Hippocampus"
        }
    }
    

The provided example demonstrates setting up a custom parcellation containing nodes for the visual network (Vis) and hippocampus regions in full:

parcel_approach = {
    "Custom": {
        "maps": "/location/to/parcellation.nii.gz",
        "nodes": [
            "LH_Vis1",
            "LH_Vis2",
            "LH_Hippocampus",
            "RH_Vis1",
            "RH_Vis2",
            "RH_Hippocampus"
        ],
        "regions": {
            "Visual": {
                "lh": [0, 1],
                "rh": [3, 4]
            },
            "Hippocampus": {
                "lh": [2],
                "rh": [5]
            }
        }
    }
}

Note: Different sub-keys are required depending on the function used. Refer to the Note section under each function for information regarding the sub-keys required for that specific function.

Methods

calculate_metrics(subject_timeseries[, tr, ...])

Compute Participant-wise CAP Metrics.

caps2corr([output_dir, suffix_title, ...])

Generate Pearson Correlation Matrix for CAPs.

caps2niftis(output_dir[, suffix_filename, ...])

Standalone Method to Convert CAPs to NifTI Statistical Maps.

caps2plot([output_dir, suffix_title, ...])

Generate Heatmaps and Outer Product Plots for CAPs.

caps2radar([output_dir, suffix_title, ...])

Generate Radar Plots for CAPs using Cosine Similarity.

caps2surf([output_dir, suffix_title, ...])

Project CAPs onto Surface Plots.

get_caps(subject_timeseries[, runs, ...])

Perform K-Means Clustering to Identify CAPs.

get_caps(subject_timeseries, runs=None, n_clusters=5, cluster_selection_method=None, random_state=None, init='k-means++', n_init='auto', max_iter=300, tol=0.0001, algorithm='lloyd', standardize=True, n_cores=None, show_figs=False, output_dir=None, **kwargs)[source]

Perform K-Means Clustering to Identify CAPs.

Concatenates the timeseries of each subject into a single numpy array with dimensions (participants x TRs) x ROI and uses sklearn.cluster.KMeans on the concatenated data. Note, KMeans uses Euclidean distance. Additionally, the Elbow method is determined using KneeLocator from the kneed package and the Davies Bouldin, Silhouette, and Variance Ratio methods are calculated using scikit-learn's davies_bouldin_score, silhouette_score, and calinski_harabasz_score functions, respectively. Note, if groups were given when the CAP class was initialized, separate KMeans models and plots will be generated for all groups.

Parameters:
  • subject_timeseries (dict[str, dict[str, np.ndarray]] or os.PathLike) --

    A dictionary mapping subject IDs to their run IDs and their associated timeseries (TRs x ROIs) as a numpy array. Can also be a path to a pickle file containing this same structure. The expected structure of is as follows:

    subject_timeseries = {
            "101": {
                "run-0": np.array([...]), # Shape: TRs x ROIs
                "run-1": np.array([...]), # Shape: TRs x ROIs
                "run-2": np.array([...]), # Shape: TRs x ROIs
            },
            "102": {
                "run-0": np.array([...]), # Shape: TRs x ROIs
                "run-1": np.array([...]), # Shape: TRs x ROIs
            }
        }
    

  • runs (int, str, list[int], list[str], or None, default=None) -- The run numbers to perform the CAPs analysis with (e.g. runs=[0, 1] or runs=["01", "02"]). If None, all runs in the subject timeseries will be concatenated into a single dataframe and subjected to k-means clustering.

  • n_clusters (int | list[int], default=5) -- The number of clusters to use for sklearn.cluster.KMeans. Can be a single integer or a list of integers (if cluster_selection_method is not None).

  • cluster_selection_method ({"elbow", "davies_bouldin", "silhouette", "variance_ratio"} or None, default=None) -- Method to find the optimal number of clusters. Options are "elbow", "davies_bouldin", "silhouette", and "variance_ratio".

  • random_state (int or None, default=None) -- The random state to use for sklearn.cluster.KMeans. Ensures reproducible results.

  • init ({"k-means++", "random"}, or np.ndarray, default="k-means++") -- Method for choosing initial cluster centroid for sklearn.cluster.KMeans. Options are "k-means++", "random", or np.ndarray.

  • n_init ({"auto"} or int, default="auto") -- Number of times sklearn.cluster.KMeans is ran with different initial clusters. The model with lowest inertia from these runs will be selected.

  • max_iter (int, default=300) -- Maximum number of iterations for a single run of sklearn.cluster.KMeans.

  • tol (float, default=1e-4,) -- Stopping criterion for sklearn.cluster.KMeans``if the change in inertia is below this value, assuming ``max_iter has not been reached.

  • algorithm ({"lloyd", "elkan"}, default="lloyd") -- The type of algorithm to use for sklearn.cluster.KMeans. Options are "lloyd" and "elkan".

  • standardize (bool, default=True) -- Standardizes the columns (ROIs) of the concatenated timeseries data. The sample standard deviation will be used, meaning Bessel's correction, n-1, will be used in the denominator.

  • n_cores (int or None, default=None) -- The number of cores to use for multiprocessing, with joblib, to run multiple sklearn.cluster.KMeans models if cluster_selection_method is not None. The default backend for joblib is used.

  • show_figs (bool, default=False) -- Displays the plots for the specified cluster_selection_method for all groups if cluster_selection_method is not None.

  • output_dir (os.PathLike or None, default=None) -- Directory to save plots as png files if cluster_selection_method is not None. The directory will be created if it does not exist. If None, plots will not be saved.

  • kwargs (dict) --

    Dictionary to adjust certain parameters when cluster_selection_method is not None. Additional parameters include:

    • S: int, default=1

      Adjusts the sensitivity of finding the elbow. Larger values are more conservative and less sensitive to small fluctuations. Passed to KneeLocator from the kneed package to. Default is 1.

    • dpi: int, default=300

      Adjusts the dpi of the plots. Default is 300.

    • figsize: tuple, default=(8, 6)

      Adjusts the size of the plots.

    • bbox_inches: str or None, default="tight"

      Alters size of the whitespace in the saved image.

    • step: int, default=None

      An integer value that controls the progression of the x-axis in plots for the specified cluster_selection_method. When set, only integer values will be displayed on the x-axis.

Returns:

matplotlib.Figure -- An instance of matplotlib.Figure.

calculate_metrics(subject_timeseries, tr=None, runs=None, continuous_runs=False, metrics=['temporal_fraction', 'persistence', 'counts', 'transition_frequency'], return_df=True, output_dir=None, prefix_filename=None)[source]

Compute Participant-wise CAP Metrics.

Uses the k-means model (or group-specific k-means models if groups specified during initialization of the CAP class) to assign each subject's TRs to a CAP. Also, creates a single pandas.DataFrame per CAP metric for all participants (with the exception of "transition_probability" which creates a single dataframe per group). As described by Liu et al., 2018 and Yang et al., 2021. The metrics include:

  • "temporal_fraction": The proportion of total volumes spent in a single CAP over all volumes in a run. Additionally, in the supplementary material of Yang et al., the stated relationship between temporal fraction, counts, and persistence is temporal fraction = (persistence*counts)/total volumes If persistence and temporal fraction is converted into time units, then temporal fraction = (persistence*counts)/(total volumes * TR).

    predicted_subject_timeseries = [1, 2, 1, 1, 1, 3]
    target = 1
    temporal_fraction = 4/6
    
  • "persistence": The average time spent in a single CAP before transitioning to another CAP (average consecutive/uninterrupted time).

    predicted_subject_timeseries = [1, 2, 1, 1, 1, 3]
    target = 1
    
    # Sequences for 1 are [1] and [1, 1, 1]; There are 2 contiguous sequences
    persistence = (1 + 3)/2
    
    # Turns average frames into average time = 4
    tr = 2
    if tr: persistence = ((1 + 3)/2)*2
    
  • "counts": The total number of initiations of a specific CAP across an entire run. An initiation is defined as the first occurrence of a CAP. If the same CAP is maintained in contiguous segment (indicating stability), it is still counted as a single initiation.

    predicted_subject_timeseries = [1, 2, 1, 1, 1, 3]
    target = 1
    
    # Initiations of CAP-1 occur at indices 0 and 2
    counts = 2
    
  • "transition_frequency": The total number of transitions to different CAPs across the entire run.

    predicted_subject_timeseries = [1, 2, 1, 1, 1, 3]
    
    # Transitions between unique CAPs occur at indices 0 -> 1, 1 -> 2, and 4 -> 5
    transition_frequency = 3
    
  • "transition_probability": The probability of transitioning from one CAP to another CAP (or the same CAP). This is calculated as (Number of transitions from A to B)/ (Total transitions from A). Note that the transition probability from CAP-A -> CAP-B is not the same as CAP-B -> CAP-A.

    # Note last two numbers in the predicted timeseries are switched for this example
    predicted_subject_timeseries = [1, 2, 1, 1, 3, 1]
    
    # If three CAPs were identified in the analysis
    combinations = [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]
    
    # Represents transition from CAP-1 -> CAP-2
    target = (1, 2)
    
    # There are 4 ones in the timeseries but only three transitions from 1; 1 -> 2, 1 -> 1, 1 -> 3
    n_transitions_from_1 = 3
    
    # There is only one 1 -> 2 transition
    transition_probability = 1/3
    
Parameters:
  • subject_timeseries (dict[str, dict[str, np.ndarray]] or os.PathLike) --

    A dictionary mapping subject IDs to their run IDs and their associated timeseries (TRs x ROIs) as a numpy array. Can also be a path to a pickle file containing this same structure. The expected structure of is as follows:

    subject_timeseries = {
            "101": {
                "run-0": np.array([...]), # Shape: TRs x ROIs
                "run-1": np.array([...]), # Shape: TRs x ROIs
                "run-2": np.array([...]), # Shape: TRs x ROIs
            },
            "102": {
                "run-0": np.array([...]), # Shape: TRs x ROIs
                "run-1": np.array([...]), # Shape: TRs x ROIs
            }
        }
    

  • tr (float or None, default=None) -- The repetition time (TR). If provided, persistence will be calculated as the average uninterrupted time spent in each CAP. If not provided, persistence will be calculated as the average uninterrupted volumes (TRs) spent in each state.

  • runs (int, str, list[int], list[str], or None, default=None) -- The run numbers to calculate CAP metrics for (e.g. runs=[0, 1] or runs=["01", "02"]). If None, CAP metrics will be calculated for each run.

  • continuous_runs (bool, default=False) --

    If True, all runs will be treated as a single, uninterrupted run.

    # CAP assignment of frames from for run_1 and run_2
    run_1 = [0, 1, 1]
    run_2 = [2, 3, 3]
    
    # Computation of each CAP metric will be conducted on the combined vector
    continuous_runs = [0, 1, 1, 2, 3, 3]
    

  • metrics ({"temporal_fraction", "persistence", "counts", "transition_frequency", "transition_probability"} or list["temporal_fraction", "persistence", "counts", "transition_frequency", "transition_probability"], default=["temporal_fraction", "persistence", "counts", "transition_frequency"]) -- The metrics to calculate. Available options include "temporal_fraction", "persistence", "counts", "transition_frequency", and "transition_probability".

  • return_df (str, default=True) -- If True, returns pandas.DataFrame inside a dictionary`, mapping each dataframe to their metric.

  • output_dir (os.PathLike or None, default=None) -- Directory to save pandas.DataFrame as csv files. The directory will be created if it does not exist. Dataframes will not be saved if None.

  • prefix_filename (str or None, default=None) --

    A prefix to append to the saved file names for each pandas.DataFrame, if output_dir is provided.

    Changed in version 0.19.0: prefix_file_name to prefix_filename

Returns:

dict[str, pd.DataFrame] or dict[str, dict[str, pd.DataFrame]] -- Dictionary containing pandas.DataFrame - one for each requested metric. In the case of "transition_probability", each group has a separate dataframe which is returned in the from of dict[str, dict[str, pd.DataFrame]].

Note

Scaling: If standardizing was requested in self.get_caps(), then the columns/ROIs of the subject_timeseries provided to this method will be scaled using the group-specific mean and sample standard deviation derived from the concatenated data.

Group-Specific CAPs: When the groups parameter is used during initialization of the CAP class, self.get_caps computes separate k-means model for each group. This means that each group has its own specific k-means model that is used for CAP metric calculations. The inclusion of all groups within the same dataframe (for "temporal_fraction", "persistence", "counts", and "transition_frequency") is primarily to reduce the number of dataframes generated. Hence, each CAP (e.g., "CAP-1") is specific to its respective groups. For instance, "CAP-1" under Group A is distinct from "CAP-1" under Group B.

For instance, if their are two groups, Group A and Group B, each with their own CAPs:

  • A has 2 CAPs: "CAP-1" and "CAP-2"

  • B has 3 CAPs: "CAP-1", "CAP-2", and "CAP-3"

The resulting "temporal_fraction" dataframe ("persistance" and "counts" have a similar structure but "transition frequency" will only contain the "Subject_ID", "Group", and "Run" columns in addition to a "Transition_Frequency" column):

With Groups

Subject_ID

Group

Run

CAP-1

CAP-2

CAP-3

101

A

run-1

0.40

0.60

NaN

102

B

run-1

0.30

0.50

0.20

...

...

...

...

...

...

The "NaN" indicates that "CAP-3" is not applicable for Group A. Additionally, "NaN" will only be observed in instances when two or more groups are specified and have different number of CAPs. As mentioned previously, "CAP-1", "CAP-2", and "CAP-3" for Group A is distinct from Group B due to using separate k-means models.

When no groups were specified during initialization of the CAP class, the resulting "temporal_fraction" dataframe (assuming four CAPs were identified in the k-means model using all participants):

Without Groups

Subject_ID

Group

Run

CAP-1

CAP-2

CAP-3

CAP-4

101

All Subjects

run-1

0.20

0

0

0.80

102

All Subjects

run-1

0.50

0.25

0.25

0

...

...

...

...

...

...

...

Transition Probability: For "transition_probability", each group has a separate dataframe to containing the CAP transitions for each group.

  • Group A Transition Probability: Stored in df_dict["transition_probability"]["A"]

  • Group B Transition Probability: Stored in df_dict["transition_probability"]["B"]

The resulting `"transition_probability"` for Group A:

Subject_ID

Group

Run

1.1

1.2

1.3

2.1

...

101

A

run-1

0.40

0.60

0

0.2

...

...

...

...

...

...

...

...

...

The resulting `"transition_probability"` for Group B:

Subject_ID

Group

Run

1.1

1.2

2.1

...

102

B

run-1

0.70

0.30

0.10

...

...

...

...

...

...

...

...

Here the columns indicate {from}.{to}. For instance, column 1.2 indicates the probability of transitioning from CAP-1 to CAP-2.

If no groups are specified, then the dataframe is stored in df_dict["transition_probability"]["All Subjects"].

For the "Group" column, whitespace in group names no longer replaced with underscores in versions >=0.17.11.

References

Liu, X., Zhang, N., Chang, C., & Duyn, J. H. (2018). Co-activation patterns in resting-state fMRI signals. NeuroImage, 180, 485–494. https://doi.org/10.1016/j.neuroimage.2018.01.041

Yang, H., Zhang, H., Di, X., Wang, S., Meng, C., Tian, L., & Biswal, B. (2021). Reproducible coactivation patterns of functional brain networks reveal the aberrant dynamic state transition in schizophrenia. NeuroImage, 237, 118193. https://doi.org/10.1016/j.neuroimage.2021.118193

caps2plot(output_dir=None, suffix_title=None, suffix_filename=None, plot_options='outer_product', visual_scope='regions', show_figs=True, subplots=False, **kwargs)[source]

Generate Heatmaps and Outer Product Plots for CAPs.

Plot CAPs as heatmaps or outer products at the node or region/network levels. This function produces a seaborn.heatmap for each CAP. Note, if groups were given when the CAP class was initialized, separate plots will be generated for all groups.

Parameters:
  • output_dir (os.PathLike or None, default=None) -- Directory for saving plots as png files. The directory will be created if it does not exist. If None, plots will not be saved.

  • suffix_title (str or None, default=None) -- Appended to the title of each plot.

  • suffix_filename (str or None, default=None) --

    Appended to the filename of each saved plot if output_dir is provided.

    Added in version 0.19.0.

  • plot_options ({"outer_product", "heatmap"} or list["outer_product", "heatmap"], default="outer_product") -- Type of plots to create. Options are "outer_product" or "heatmap".

  • visual_scope ({"regions", "nodes"} or list["regions", "nodes"], default="regions") -- Determines whether plotting is done at the region level or node level. For "regions", the values of all nodes in the same regions (including both hemispheres) are averaged together then plotted. For "nodes", plots individual node values separately.

  • show_figs (bool, default=True) -- Display figures.

  • subplots (bool, default=True) -- Produce subplots for outer product plots, combining all plots into a single figure.

  • kwargs (dict) --

    Keyword arguments used when saving figures. Valid keywords include:

    • dpi: int, default=300

      Dots per inch for the figure. Default is 300 if output_dir is provided and dpi is not specified.

    • figsize: tuple, default=(8, 6)

      Size of the figure in inches.

    • fontsize: int, default=14

      Font size for the title of individual plots or subplots.

    • hspace: float, default=0.4

      Height space between subplots.

    • wspace: float, default=0.4

      Width space between subplots.

    • xticklabels_size: int, default=8

      Font size for x-axis tick labels.

    • yticklabels_size: int, default=8

      Font size for y-axis tick labels.

    • shrink: float, default=0.8

      Fraction by which to shrink the colorbar.

    • cbarlabels_size: int, default=8

      Font size for the colorbar labels.

    • nrow: int, default=varies (max 5)

      Number of rows for subplots. Default varies but the maximum is 5.

    • ncol: int or None, default=None

      Number of columns for subplots. Default varies but the maximum is 5.

    • suptitle_fontsize: float, default=0.7

      Font size for the main title when subplot is True.

    • tight_layout: bool, default=True

      Use tight layout for subplots.

    • rect: list[int], default=[0, 0.03, 1, 0.95]

      Rectangle parameter for tight layout when subplots are True to fix whitespace issues.

    • sharey: bool, default=True

      Share y-axis labels for subplots.

    • xlabel_rotation: int, default=0

      Rotation angle for x-axis labels.

    • ylabel_rotation: int, default=0

      Rotation angle for y-axis labels.

    • annot: bool, default=False

      Add values to cells.

    • annot_kws: dict, default=None,

      Customize the annotations.

    • fmt: str, default=".2g"

      Modify how the annotated vales are presented.

    • linewidths: float, default=0

      Padding between each cell in the plot.

    • borderwidths: float, default=0

      Width of the border around the plot.

    • linecolor: str, default="black"

      Color of the line that seperates each cell.

    • edgecolors: str or None, default=None

      Color of the edges.

    • alpha: float or None, default=None

      Controls transparency and ranges from 0 (transparent) to 1 (opaque).

    • bbox_inches: str or None, default="tight"

      Alters size of the whitespace in the saved image.

    • hemisphere_labels: bool, default=False

      Only available when visual_scope="nodes". Simplifies node labels to show only left/right hemisphere divisions with a separation line, rather than listing individual node labels. If set to True, edgecolors is ignored and linewidths and linecolor affect only the hemisphere division line. This option is available exclusively for "Custom" and "Schaefer" parcellations. Note, for the "Custom" parcellations, nodes must be ordered with left hemisphere nodes first, followed by right hemisphere nodes.

    • cmap: str or callable default="coolwarm"

      Color map for the plot cells. For this parameter, you can use pre-made color palettes or create custom ones. Below is a list of valid options:

      • Strings to call seaborn's pre-made palettes.

      • seaborn.diverging_palette function to generate custom palettes.

      • matplotlib.colors.LinearSegmentedColormap to generate custom palettes.

    • vmin: float or None, default=None

      The minimum value to display in colormap.

    • vmax: float or None, default=None

      The maximum value to display in colormap.

Returns:

seaborn.heatmap -- An instance of seaborn.heatmap.

Note

Parcellation Approach: the "nodes" and "regions" sub-keys are required in parcel_approach for this function.

Color Palettes: For valid pre-made palettes for seaborn, refer to https://seaborn.pydata.org/tutorial/color_palettes.html

caps2corr(output_dir=None, suffix_title=None, suffix_filename=None, show_figs=True, save_plots=True, return_df=False, save_df=False, **kwargs)[source]

Generate Pearson Correlation Matrix for CAPs.

Produces a correlation matrix of all CAPs and visualizes it using seaborn.heatmap. Can also produce a pandas Dataframe of the correlation matrix where each element contains its uncorrected p-value in parenthesis, with a single asterisk if < 0.05, a double asterisk if < 0.01, and a triple asterisk < 0.001. Note, if groups were given when the CAP class was initialized, separate correlation matrices will be generated for all groups.

Parameters:
  • output_dir (os.PathLike or None, default=None) -- Directory to save plots (if save_plots is True) and correlation matrices DataFrames (if save_df is True). The directory will be created if it does not exist. If None, plots and dataFrame will not be saved.

  • suffix_title (str or None, default=None) -- Appended to the title of each plot.

  • suffix_filename (str or None, default=None) --

    Appended to the filename of each saved plot if output_dir is provided.

    Added in version 0.19.0.

  • show_figs (bool, default=True) -- Display figures.

  • save_plots (bool, default=True) -- If True, plots are saves as png images. For this to be used, output_dir must be specified.

  • return_df (bool, default=False) -- If True, returns a dictionary with a correlation matrix for each group.

  • save_df (bool, default=False,) -- If True, saves the correlation matrix contained in the DataFrames as csv files. For this to be used, output_dir must be specified.

  • kwargs (dict) --

    Keyword arguments used when modifying figures. Valid keywords include:

    • dpi: int, default=300

      Dots per inch for the figure. Default is 300 if output_dir is provided and dpi is not specified.

    • figsize: tuple, default=(8, 6)

      Size of the figure in inches.

    • fontsize: int, default=14

      Font size for the title each plot.

    • xticklabels_size: int, default=8

      Font size for x-axis tick labels.

    • yticklabels_size: int, default=8

      Font size for y-axis tick labels.

    • shrink: float, default=0.8

      Fraction by which to shrink the colorbar.

    • cbarlabels_size: int, default=8

      Font size for the colorbar labels.

    • xlabel_rotation: int, default=0

      Rotation angle for x-axis labels.

    • ylabel_rotation: int, default=0

      Rotation angle for y-axis labels.

    • annot: bool, default=False

      Add values to each cell.

    • annot_kws: dict, default=None,

      Customize the annotations.

    • fmt: str, default=".2g",

      Modify how the annotated vales are presented.

    • linewidths: float, default=0

      Padding between each cell in the plot.

    • borderwidths: float, default=0

      Width of the border around the plot.

    • linecolor: str, default="black"

      Color of the line that seperates each cell.

    • edgecolors: str or None, default=None

      Color of the edges.

    • alpha: float or None, default=None

      Controls transparency and ranges from 0 (transparent) to 1 (opaque).

    • bbox_inches: str or None, default="tight"

      Alters size of the whitespace in the saved image.

    • cmap: str, callable default="coolwarm"

      Color map for the plot cells. For this parameter, you can use pre-made color palettes or create custom ones. Below is a list of valid options:

      • Strings to call seaborn's pre-made palettes.

      • seaborn.diverging_palette function to generate custom palettes.

      • matplotlib.color.LinearSegmentedColormap to generate custom palettes.

    • vmin: float or None, default=None

      The minimum value to display in colormap.

    • vmax: float or None, default=None

      The maximum value to display in colormap.

Returns:

  • seaborn.heatmap -- An instance of seaborn.heatmap.

  • dict[str, pd.DataFrame] -- An instance of a pandas DataFrame for each group.

Note

Color Palettes: For valid pre-made palettes for seaborn, refer to https://seaborn.pydata.org/tutorial/color_palettes.html

caps2niftis(output_dir, suffix_filename=None, fwhm=None, knn_dict=None)[source]

Standalone Method to Convert CAPs to NifTI Statistical Maps.

Projects CAPs onto parcellation to create NifTI statistical maps by replacing parcellation labels with their corresponding CAP (cluster centroid) values. Creates compressed NifTI (.nii.gz) files. One image is generated per CAP. Note, if groups were given when the CAP class was initialized, separate NifTI images will be generated per CAP for all groups.

Parameters:
  • output_dir (os.PathLike) -- Directory to save nii.gz files. The directory will be created if it does not exist.

  • suffix_filename (str or None, default=None) --

    Appended to the name of the saved file.

    Changed in version 0.19.0: suffix_file_name to suffix_filename

  • fwhm (float or None, default=None) -- Strength of spatial smoothing to apply (in millimeters) to the statistical map prior to interpolating from MNI152 space to fslr surface space. Uses nilearn.image.smooth_img.

  • knn_dict (dict[str, int | bool], default=None) --

    Use KNN (k-nearest neighbors) interpolation to fill in non-background coordinates that are assigned zero. This is primarily used as a fix for when a custom parcellation does not project well from volumetric to surface space. This method involves resampling a reference volumetric parcellation that projects well onto surface space (Schaefer or AAL), to the target parcellation specified in the "maps" sub-key in self.parcel_approach. The background coordinates are extracted from the reference parcellation and are used to obtain the non-background coordinates that are set to zero in the target parcellation. These coordinates are then replaced with the value of the nearest neighbor, determined by the sub-key "k". The following sub-keys are recognized:

    • "k": An integer that determines the number of nearest neighbors to consider, with the majority vote determining the new value. If not specified, the default is 1.

    • "reference_atlas": A string specifying the atlas to use as a reference to determine the background indices to not interpolate. Options includes "Schaefer" or "AAL". If not specified the default will be "Schaefer".

    • "resolution_mm": An integer (1 or 2) that determines the resolution of the Schaefer parcellation. If not specified, the default is 1. Only used when "reference_atlas" is "Schaefer".

    • "remove_labels": A list or array of label IDs as integers of the regions in the parcellation to not interpolate.

    This method is applied before the fwhm.

    Added in version 0.18.0: "reference_atlas"

    Changed in version 0.18.0: "remove_subcortical" key changed to "remove_labels" and default of "k" changed 1 to 3

Returns:

NifTI1Image -- NifTI statistical map.

Note

Assumption: This function assumes that the background label for the parcellation is zero. Additionaly, the following approach is used to map each CAP onto the parcellation.

atlas = nib.load(atlas_file)
atlas_fdata = atlas.get_fdata()
# Create array of zeroes with same dimensions as atlas
atlas_array = np.zeros_like(atlas_fdata)

# Get array containing all labels in parcellation in order
target_array = sorted(np.unique(atlas_fdata))

# Start at 1 to avoid assigment to the background label
for indx, value in enumerate(cap_vector, start=1):
    atlas_array[np.where(atlas_fdata == target_array[indx])] = value
caps2surf(output_dir=None, suffix_title=None, suffix_filename=None, show_figs=True, fwhm=None, fslr_density='32k', method='linear', save_stat_maps=False, fslr_giftis_dict=None, knn_dict=None, **kwargs)[source]

Project CAPs onto Surface Plots.

Plot CAPs on cortical surface in fsLR space. First, projects CAPs onto parcellation to create NifTI statistical maps by replacing parcellation labels with their corresponding CAP (cluster centroid) values. Then uses neuromap's transforms.mni152_to_fslr for coordinate system transformation and surfplot's Plot for plotting. If CAPs where already converted to NifTI (self.caps2niftis) and transformed to fsLR GifTI files externally, these can be provided using the fslr_giftis_dict parameter and will be converted to a suitable format for surfplot's Plot function by using neuromap's transforms.fslr_to_fslr function. Note, if groups were given when the CAP class was initialized, surface plots will be generated per CAP for all groups.

Parameters:
  • output_dir (os.PathLike or None, default=None) -- Directory to save plots as png files. The directory will be created if it does not exist. If None, plots will not be saved.

  • suffix_title (str or None, default=None) -- Appended to the title of each plot.

  • suffix_filename (str or None, default=None) --

    Appended to the filename of each saved plot if output_dir is provided.

    Added in version 0.19.0.

  • show_figs (bool, default=True) -- Display figures.

  • fwhm (float or None, defualt=None) -- Strength of spatial smoothing to apply (in millimeters) to the statistical map prior to interpolating from MNI152 space to fsLR surface space. Uses nilearn's image.smooth.

  • fslr_density ({"4k", "8k", "32k", "164k"}, default="32k") -- Density of the fsLR surface when converting from MNI152 space to fsLR surface. Options are "32k" or "164k". If using fslr_giftis_dict options are "4k", "8k", "32k", and "164k".

  • method ({"linear", "nearest"}, default="linear") -- Interpolation method to use when converting from MNI152 space to fsLR surface or from fsLR to fsLR. Options are "linear" or "nearest".

  • save_stat_maps (bool, default=False) -- If True, saves the statistical map for each CAP for all groups as a Nifti1Image if output_dir is provided.

  • fslr_giftis_dict (dict or None, default=None) --

    Dictionary specifying precomputed GifTI files in fsLR space for plotting statistical maps. This parameter should be used if the statistical CAP NIfTI files (can be obtained using self.caps2niftis) were converted to GifTI files using a tool such as Connectome Workbench. The dictionary structure is:

    {
        "GroupName": {
            "CAP-Name": {
                "lh": "path/to/left_hemisphere_gifti",
                "rh": "path/to/right_hemisphere_gifti"
            }
        }
    }
    

    GroupName can be "All Subjects" or any specific group name. CAP-Name is the name of the CAP. This parameter allows plotting without re-running the analysis. Initialize the CAP class and use this method if using this parameter.

  • knn_dict (dict[str, int | bool], default=None) --

    Use KNN (k-nearest neighbors) interpolation to fill in non-background coordinates that are assigned zero. This is primarily used as a fix for when a custom parcellation does not project well from volumetric to surface space. This method involves resampling a reference volumetric parcellation that projects well onto surface space (Schaefer or AAL), to the target parcellation specified in the "maps" sub-key in self.parcel_approach. The background coordinates are extracted from the reference parcellation and are used to obtain the non-background coordinates that are set to zero in the target parcellation. These coordinates are then replaced with the value of the nearest neighbor, determined by the sub-key "k". The following sub-keys are recognized:

    • "k": An integer that determines the number of nearest neighbors to consider, with the majority vote determining the new value. If not specified, the default is 1.

    • "reference_atlas": A string specifying the atlas to use as a reference to determine the background indices to not interpolate. Options includes "AAL" or "Schaefer". If not specified the default will be "Schaefer".

    • "resolution_mm": An integer (1 or 2) that determines the resolution of the Schaefer parcellation. If not specified, the default is 1. Only used when "reference_atlas" is "Schaefer".

    • "remove_labels": A list or array of label IDs as integers of the regions in the parcellation to not interpolate.

    This method is applied before the fwhm.

    Added in version 0.18.0: "reference_atlas" key added

    Changed in version 0.18.0: "remove_subcortical" key changed to "remove_labels"

  • kwargs (dict) --

    Additional parameters to pass to modify certain plot parameters. Options include:

    • dpi: int, default=300

      Dots per inch for the plot.

    • title_pad: int, default=-3

      Padding for the plot title.

    • cmap: str or callable, default="cold_hot"

      Colormap to be used for the plot. For this parameter, you can use pre-made color palettes or create custom ones. Below is a list of valid options:

      • Strings to call nilearn.plotting.cm._cmap_d fuction.

      • matplotlib.colors.LinearSegmentedColormap to generate custom colormaps.

    • cbar_kws: dict, default={"location": "bottom", "n_ticks": 3}

      Customize colorbar. Refer to _add_colorbars at for valid kwargs in surfplot.plotting.Plot documentation listed in the Note section.

    • alpha: float, default=1

      Transparency level of the colorbar.

    • outline_alpha: float, default=1

      Transparency level of the colorbar for outline if as_outline is True.

    • zero_transparent: bool, default=True

      Turns vertices with a value of 0 transparent.

    • as_outline: bool, default=False

      Plots only an outline of contiguous vertices with the same value.

    • size: tuple, default=(500, 400)

      Size of the plot in pixels.

    • layout: str, default="grid"

      Layout of the plot.

    • zoom: float, default=1.5

      Zoom level for the plot.

    • views: {"lateral", "medial"} or list[{"lateral", "medial}], default=["lateral", "medial"]

      Views to be displayed in the plot.

    • brightness: float, default=0.5

      Brightness level of the plot.

    • figsize: tuple or None, default=None

      Size of the figure.

    • scale: tuple, default=(2, 2)

      Scale factors for the plot.

    • surface: {"inflated", "veryinflated"}, default="inflated"

      The surface atlas that is used for plotting. Options are "inflated" or "veryinflated".

    • color_range: tuple or None, default=None

      The minimum and maximum value to display in plots. For instance, (-1, 1) where minimum value is first. If None, the minimum and maximum values from the image will be used.

    • bbox_inches: str or None, default="tight"

      Alters size of the whitespace in the saved image.

Returns:

  • NifTI1Image -- NifTI statistical map.

  • surfplot.plotting.Plot -- An instance of surfplot.plotting.Plot.

Note

Parcellation Approach: parcel_approach must have the "maps" sub-key containing the path to th NifTI file of the parcellation.

Assumptions: This function assumes that the background label for the parcellation is zero and that is in MNI space. Additionally, the following approach is taken to map the each CAP onto the parcellation

atlas = nib.load(atlas_file)
atlas_fdata = atlas.get_fdata()
# Create array of zeroes with same dimensions as atlas
atlas_array = np.zeros_like(atlas_fdata)

# Get array containing all labels in parcellation in order
target_array = sorted(np.unique(atlas_fdata))

# Start at 1 to avoid assigment to the background label
for indx, value in enumerate(cap_vector, start=1):
    atlas_array[np.where(atlas_fdata == target_array[indx])] = value
caps2radar(output_dir=None, suffix_title=None, suffix_filename=None, show_figs=True, use_scatterpolar=False, as_html=False, **kwargs)[source]

Generate Radar Plots for CAPs using Cosine Similarity.

Calculates the cosine similarity between the "High Amplitude" (positive/above the mean) and "Low Amplitude" (negative/below the mean) activations of the CAP cluster centroid and each a-priori region or network in a parcellation. This function assumes the mean for each ROI is 0 due to standardization.

Cosine similarity is computed separately for high and low amplitudes by comparing them to the binary vector of the a-priori region, representing the region or network of interest. This provides a measure of how closely the CAP's positive and negative activation patterns align with each selected region.

The process involves the following steps:

  1. Extract Cluster Centroids:

  • Each CAP is represented by a cluster centroid, which is a 1 x ROI (Region of Interest) vector.

  1. Generate Binary Vectors:

  • For each region create a binary vector (1 x ROI) where 1 indicates that the ROI is part of the specific region and 0 otherwise.

  • In this example, the binary vector acts as a 1D mask to isolate ROIs in the Visual Network by setting the corresponding indices to 1.

    import numpy as np
    
    # Define nodes with their corresponding label IDs
    nodes = ["LH_Vis1", "LH_Vis2", "LH_SomSot1", "LH_SomSot2",
             "RH_Vis1", "RH_Vis2", "RH_SomSot1", "RH_SomSot2"]
    
    # Binary mask for the Visual Network (Vis)
    binary_vector = np.array([1, 1, 0, 0, 1, 1, 0, 0])
    
  1. Isolate Positive and Negative Activations in CAP Centroid:

  • Positive activations are defined as the values in the CAP centroid that are greater than zero. These values represent the "High Amplitude" activations for that CAP.

  • Negative activations are defined as the values in the CAP centroid that are less than zero. These values represent the "Low Amplitude" activations for that CAP.

  • To simplify the comparison between positive and negative activations using cosine similarity, the negative activations are inverted (i.e., multiplied by -1). This inversion converts the negative values into positive ones, allowing the cosine similarity calculation to return a positive value. The positive similarity score represents how closely the a-priori region aligns with both the high and low amplitude aspects of the CAP.

    # Example cluster centroid for CAP 1
    cap_1_cluster_centroid = np.array([-0.3, 1.5, 2.0, -0.2, 0.7, 1.3, -0.5, 0.4])
    
    # Assign values less than 0 as 0 to isolate the high amplitude activations
    high_amp = np.where(cap_1_cluster_centroid > 0, cap_1_cluster_centroid, 0)
    
    # Assign values less than 0 as 0 to isolate the low amplitude activations; Also invert the sign
    low_amp = high_amp = np.where(cap_1_cluster_centroid < 0, -cap_1_cluster_centroid, 0)
    
  1. Calculate Cosine Similarity:

  • Normalize the dot product by the product of the Euclidean norms of the cluster centroid and the binary vector to obtain the cosine similarity:

    # Compute dot product between the binary vector with the positive and negative activations
    high_dot = np.dot(high_amp, binary_vector)
    low_dot = np.dot(low_amp, binary_vector)
    
    # Compute the norms
    high_norm = np.linalg.norm(high_amp)
    low_norm = np.linalg.norm(low_amp)
    bin_norm = np.linalg.norm(binary_vector)
    
    # Calculate cosine similarity
    high_cos = high_dot / (high_norm * bin_norm)
    low_cos = low_dot / (low_norm * bin_norm)
    
  1. Generate Radar Plots of Each CAPs:

  • Each radar plot visualizes the cosine similarity for both "High Amplitude" (positive) and "Low Amplitude" (negative) activations of the CAP. The cosine similarity values range from 0 to 1, representing how closely the a-priori region aligns with the positive and negative activations of the CAP centroid.

Note, if groups were given when the CAP class was initialized, separate radar plots will be generated per CAP for all groups.

Parameters:
  • output_dir (os.PathLike or None, default=None) -- Directory to save plots as png or html images. The directory will be created if it does not exist. If None, plots will not be saved.

  • suffix_title (str or None, default=None) -- Appended to the title of each plot.

  • suffix_filename (str or None, default=None) --

    Appended to the filename of each saved plot if output_dir is provided.

    Added in version 0.19.0.

  • show_figs (bool, default=True) -- Display figures. If this function detects that it is not being ran in an interactive Python environment, then it uses plotly.offline, creates an html file named "temp-plot.html", and opens each plot in the default browser.

  • use_scatterpolar (bool, default=False) -- Uses plotly.graph_objects.Scatterpolar instead of plotly.express.line_polar. The primary difference is that plotly.graph_objects.Scatterpolar shows the scatter dots. However, this can be acheived with plotly.express.line_polar by setting mode to "markers+lines". There also seems to be a difference in default opacity behavior.

  • as_html (bool, default=False) -- When output_dir is specified, plots are saved as html images instead of png images. The advantage is that plotly's radar plots will retain its interactive properties, can be opened in a browser.

  • kwargs (dict) --

    Additional parameters to pass to modify certain plot parameters. Options include:

    • scale: int, default=2

      If output_dir provided, controls resolution of image when saving. Serves a similar purpose as dpi.

    • savefig_options: dict[str], default={"width": 3, "height": 3, "scale": 1}

      If output_dir provided, controls the width (in inches), height (in inches), and scale of the plot. The height and width are multiplied by the dpi.

    • height: int, default=800

      Height of the plot. Value is multiplied by the dpi when saving.

    • width: int, defualt=1200

      Width of the plot. Value is multiplied by the dpi when saving.

    • line_close: bool, default=True

      Whether to close the lines

    • bgcolor: str, default="white"

      Color of the background

    • scattersize: int, default=8

      Controls size of the dots when markers are used.

    • connectgaps: bool, default=True

      If use_scatterpolar=True, controls if missing values are connected.

    • linewidth: int, default = 2

      The width of the line connecting the values if use_scatterpolar=True.

    • opacity: float, default=0.5,

      If use_scatterpolar=True, sets the opacity of the trace.

    • fill: str, default="none".

      If "toself" the are of the dots and within the boundaries of the line will be filled.

    • mode: str, default="markers+lines",

      Determines how the trace is drawn. Can include "lines", "markers", "lines+markers", "lines+markers+text".

    • radialaxis: dict, default={"showline": False, "linewidth": 2, "linecolor": "rgba(0, 0, 0, 0.25)", "gridcolor": "rgba(0, 0, 0, 0.25)", "ticks": "outside", "tickfont": {"size": 14, "color": "black"}}

      Customizes the radial axis.

    • angularaxis: dict, default={"showline": True, "linewidth": 2, "linecolor": "rgba(0, 0, 0, 0.25)", "gridcolor": "rgba(0, 0, 0, 0.25)", "tickfont": {"size": 16, "color": "black"}}

      Customizes the angular axis.

    • color_discrete_map: dict, default={"High Amplitude": "red", "Low Amplitude": "blue"},

      Change color of the "High Amplitude" and "Low Amplitude" groups. Must use the keys "High Amplitude" and "Low Amplitude" to work.

    • title_font: dict, default={"family": "Times New Roman", "size": 30, "color": "black"}

      Modifies the font of the title.

    • title_x: float, default=0.5

      Modifies x position of title.

    • title_y: float, default=None

      Modifies y position of title.

    • legend: dict, default={"yanchor": "top", "xanchor": "left", "y": 0.99, "x": 0.01, "title_font_family": "Times New Roman", "font": {"size": 12, "color": "black"}}

      Customizes the legend.

    • engine: {"kaleido", "orca"}, default="kaleido"

      Engine used for saving plots.

Returns:

  • plotly.express.line_polar -- An instance of plotly.express.line_polar.

  • plotly.graph_objects.Scatterpolar -- An instance of plotly.graph_objects.Scatterpolar.

Note

Saving Plots: By default, this function uses "kaleido" (which is also a dependency in this package) to save plots. For other engines such as "orca", those packages must be installed seperately.

Parcellation Approach: If using "Custom" for parcel_approach the "regions" sub-key is required.

Tick Values: if the tickvals or range sub-keys in this code are not specified in the radialaxis kwarg, then four values are shown - 0.25*(max value), 0.50*(max value), 0.75*(max value), and the max value. These values are also rounded to the second decimal place.

Radial Axis Kwargs: For valid keys for radialaxis refer to plotly's documentation at https://plotly.com/python-api-reference/generated/plotly.graph_objects.layout.polar.radialaxis.html or https://plotly.com/python/reference/layout/polar/ for valid kwargs.

Angular Axis Kwargs: For valid keys for angularaxis refer to plotly's documentation at https://plotly.com/python-api-reference/generated/plotly.graph_objects.layout.polar.angularaxis.html or https://plotly.com/python/reference/layout/polar/ for valid kwargs.

Legend and Title Font Kwargs: For valid keys for legend and title_font, refer to plotly's documentation at https://plotly.com/python/reference/layout/ for valid kwargs.

References

Zhang, R., Yan, W., Manza, P., Shokri-Kojori, E., Demiral, S. B., Schwandt, M., Vines, L., Sotelo, D., Tomasi, D., Giddens, N. T., Wang, G., Diazgranados, N., Momenan, R., & Volkow, N. D. (2023). Disrupted brain state dynamics in opioid and alcohol use disorder: attenuation by nicotine use. Neuropsychopharmacology, 49(5), 876–884. https://doi.org/10.1038/s41386-023-01750-w

Ingwersen, T., Mayer, C., Petersen, M., Frey, B. M., Fiehler, J., Hanning, U., Kühn, S., Gallinat, J., Twerenbold, R., Gerloff, C., Cheng, B., Thomalla, G., & Schlemm, E. (2024). Functional MRI brain state occupancy in the presence of cerebral small vessel disease — A pre-registered replication analysis of the Hamburg City Health Study. Imaging Neuroscience, 2, 1–17. https://doi.org/10.1162/imag_a_00122