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]], oros.PathLike, default=None) --The approach used to parcellate NifTI images. Similar to
TimeseriesExtractor, "Schaefer" and "AAL" can be initialized here to create the appropriateparcel_approachthat 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_approachwas initialized inTimeSeriesExtractorclass, then this parameter can be set toself.parcel_approach. Refer to documentation from nilearn'sdatasets.fetch_atlas_schaefer_2018anddatasets.fetch_atlas_aalfunctions 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]]orNone, 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:
intorlist[int] An integer or list of integers (if
cluster_selection_methodis not None) that was used forsklearn.cluster.KMeansinself.get_caps().- groups:
dict[str, list[str]]orNone: A mapping of groups names to unique subject IDs.
- cluster_selection_method:
strorNone: 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 andn_coresis specified.- runs:
intorlist[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_capsis 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.KMeansmodel to each group whenself.get_caps()is used. Ifcluster_selection_methodis used, the model stored in this property is the optimal k-means model. The structure is as follows:{ "GroupName": sklearn.cluster.KMeans, }
- davies_bouldin:
dict[str, dict[str, float]] A dictionary mapping groups to the assessed cluster sizes and corresponding davies bouldin score if
cluster_selection_methodinself.get_caps()is set to "variance_ratio". The structure is as follows:{ "GroupName": { 2: float, 3: float, 4: float, } }
- inertia:
dict[str, dict[str, float]] A dictionary mapping groups to the assessed cluster sizes and corresponding inertia score if
cluster_selection_methodinself.get_caps()is set to "variance_ratio". The structure is as follows:{ "GroupName": { 2: float, 3: float, 4: float, } }
- silhouette_scores:
dict[str, dict[str, float]] A dictionary mapping groups to the assessed cluster sizes and corresponding silhouette score if
cluster_selection_methodinself.get_caps()is set to "variance_ratio". The structure is as follows:{ "GroupName": { 2: float, 3: float, 4: float, } }
- variance_ratio:
dict[str, dict[str, float]] A dictionary mapping groups to the assessed cluster sizes and corresponding variance ratio score if
cluster_selection_methodinself.get_caps()is set to "variance_ratio". The structure is as follows:{ "GroupName": { 2: float, 3: float, 4: float, } }
- 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_methodis not None inself.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
standardizeis True inself.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
standardizeis True inself.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,delattr(self, "_concatenated_timeseries")to delete this property is there are memory issues. 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_scopeset to "regions" inself.caps2plot(). The position of elements corresponds to "regions" inparcel_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_optionsset 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_file_name, ...])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.KMeanson the concatenated data. Note,KMeansuses Euclidean distance. Additionally, the Elbow method is determined usingKneeLocatorfrom the kneed package and the Davies Bouldin, Silhouette, and Variance Ratio methods are calculated using scikit-learn'sdavies_bouldin_score,silhouette_score, andcalinski_harabasz_scorefunctions, respectively. Note, if groups were given when theCAPclass was initialized, separateKMeansmodels and plots will be generated for all groups.- Parameters:
subject_timeseries (
dict[str, dict[str, np.ndarray]]oros.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], orNone, default=None) -- The run numbers to perform the CAPs analysis with (e.g.runs=[0, 1]orruns=["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 forsklearn.cluster.KMeans. Can be a single integer or a list of integers (ifcluster_selection_methodis 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 (
intorNone, default=None) -- The random state to use forsklearn.cluster.KMeans. Ensures reproducible results.init ({"k-means++", "random"}, or
np.ndarray, default="k-means++") -- Method for choosing initial cluster centroid forsklearn.cluster.KMeans. Options are "k-means++", "random", or np.ndarray.n_init ({"auto"} or
int, default="auto") -- Number of timessklearn.cluster.KMeansis 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 ofsklearn.cluster.KMeans.tol (
float, default=1e-4,) -- Stopping criterion forsklearn.cluster.KMeans``if the change in inertia is below this value, assuming ``max_iterhas 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 (
intorNone, default=None) -- The number of cores to use for multiprocessing, with joblib, to run multiplesklearn.cluster.KMeansmodels ifcluster_selection_methodis not None. The default backend for joblib is used.show_figs (
bool, default=False) -- Displays the plots for the specifiedcluster_selection_methodfor all groups ifcluster_selection_methodis not None.output_dir (
os.PathLikeorNone, default=None) -- Directory to save plots as png files ifcluster_selection_methodis 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_methodis 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
KneeLocatorfrom the kneed package to. Default is 1.
- S:
- dpi:
int, default=300 Adjusts the dpi of the plots. Default is 300.
- dpi:
- figsize:
tuple, default=(8, 6) Adjusts the size of the plots.
- figsize:
- bbox_inches:
strorNone, default="tight" Alters size of the whitespace in the saved image.
- bbox_inches:
- 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.
- step:
- 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_file_name=None)[source]
Compute Participant-wise CAP Metrics.
Uses the k-means model (or group-specific k-means models if
groupsspecified during initialization of theCAPclass) to assign each subject's TRs to a CAP. Also, creates a singlepandas.DataFrameper 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, thentemporal 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]]oros.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 (
floatorNone, 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], orNone, default=None) -- The run numbers to calculate CAP metrics for (e.g.runs=[0, 1]orruns=["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]
Changed in version 0.17.11: the label in the "Run" column in the dataframe changed from "continuous_runs" to "run-continuous"
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".
Added in version 0.16.2: "transition_probabilities"
Changed in version 0.16.6: calculation for "counts" has changed to align with the equation, temporal fraction = (persistence*counts)/total volumes, which can be found in the supplemental material of Yang et al., 2022
return_df (
str, default=True) -- If True, returnspandas.DataFrameinside a dictionary`, mapping each dataframe to their metric.output_dir (
os.PathLikeorNone, default=None) -- Directory to savepandas.DataFrameas csv files. The directory will be created if it does not exist. Dataframes will not be saved if None.prefix_file_name (
strorNone, default=None) -- A prefix to append to the saved file names for eachpandas.DataFrame, ifoutput_diris provided.
- 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 thesubject_timeseriesprovided 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
groupsparameter is used during initialization of theCAPclass,self.get_capscomputes 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
CAPclass, 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, 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.heatmapfor each CAP. Note, if groups were given when theCAPclass was initialized, separate plots will be generated for all groups.- Parameters:
output_dir (
os.PathLikeorNone, 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 (
strorNone, default=None) -- Appended to the title of each plot as well as the name of the saved file ifoutput_diris provided.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_diris provided anddpiis not specified.
- dpi:
- figsize:
tuple, default=(8, 6) Size of the figure in inches.
- figsize:
- fontsize:
int, default=14 Font size for the title of individual plots or subplots.
- fontsize:
- hspace:
float, default=0.4 Height space between subplots.
- hspace:
- wspace:
float, default=0.4 Width space between subplots.
- wspace:
- xticklabels_size:
int, default=8 Font size for x-axis tick labels.
- xticklabels_size:
- yticklabels_size:
int, default=8 Font size for y-axis tick labels.
- yticklabels_size:
- shrink:
float, default=0.8 Fraction by which to shrink the colorbar.
- shrink:
- cbarlabels_size:
int, default=8 Font size for the colorbar labels.
- cbarlabels_size:
- nrow:
int, default=varies (max 5) Number of rows for subplots. Default varies but the maximum is 5.
- nrow:
- ncol:
intorNone, default=None Number of columns for subplots. Default varies but the maximum is 5.
- ncol:
- suptitle_fontsize:
float, default=0.7 Font size for the main title when subplot is True.
- suptitle_fontsize:
- tight_layout:
bool, default=True Use tight layout for subplots.
- tight_layout:
- rect:
list[int], default=[0, 0.03, 1, 0.95] Rectangle parameter for tight layout when subplots are True to fix whitespace issues.
- rect:
- sharey:
bool, default=True Share y-axis labels for subplots.
- sharey:
- xlabel_rotation:
int, default=0 Rotation angle for x-axis labels.
- xlabel_rotation:
- ylabel_rotation:
int, default=0 Rotation angle for y-axis labels.
- ylabel_rotation:
- annot:
bool, default=False Add values to cells.
- annot:
- annot_kws:
dict, default=None, Customize the annotations.
- annot_kws:
- fmt:
str, default=".2g" Modify how the annotated vales are presented.
- fmt:
- linewidths:
float, default=0 Padding between each cell in the plot.
- linewidths:
- borderwidths:
float, default=0 Width of the border around the plot.
- borderwidths:
- linecolor:
str, default="black" Color of the line that seperates each cell.
- linecolor:
- edgecolors:
strorNone, default=None Color of the edges.
- edgecolors:
- alpha:
floatorNone, default=None Controls transparency and ranges from 0 (transparent) to 1 (opaque).
- alpha:
- bbox_inches:
strorNone, default="tight" Alters size of the whitespace in the saved image.
- bbox_inches:
- 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,edgecolorsis ignored andlinewidthsandlinecoloraffect 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.
- hemisphere_labels:
- cmap:
strorcallabledefault="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_palettefunction to generate custom palettes.matplotlib.colors.LinearSegmentedColormapto generate custom palettes.
- cmap:
- vmin:
floatorNone, default=None The minimum value to display in colormap.
- vmin:
- vmax:
floatorNone, default=None The maximum value to display in colormap.
- vmax:
- Returns:
seaborn.heatmap -- An instance of seaborn.heatmap.
Note
Parcellation Approach: the "nodes" and "regions" sub-keys are required in
parcel_approachfor 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, 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 theCAPclass was initialized, separate correlation matrices will be generated for all groups.- Parameters:
output_dir (
os.PathLikeorNone, default=None) -- Directory to save plots (ifsave_plotsis True) and correlation matrices DataFrames (ifsave_dfis True). The directory will be created if it does not exist. If None, plots and dataFrame will not be saved.suffix_title (
strorNone, default=None) -- Appended to the title of each plot as well as the name of the saved file ifoutput_diris provided.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_dirmust 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_dirmust 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_diris provided anddpiis not specified.
- dpi:
- figsize:
tuple, default=(8, 6) Size of the figure in inches.
- figsize:
- fontsize:
int, default=14 Font size for the title each plot.
- fontsize:
- xticklabels_size:
int, default=8 Font size for x-axis tick labels.
- xticklabels_size:
- yticklabels_size:
int, default=8 Font size for y-axis tick labels.
- yticklabels_size:
- shrink:
float, default=0.8 Fraction by which to shrink the colorbar.
- shrink:
- cbarlabels_size:
int, default=8 Font size for the colorbar labels.
- cbarlabels_size:
- xlabel_rotation:
int, default=0 Rotation angle for x-axis labels.
- xlabel_rotation:
- ylabel_rotation:
int, default=0 Rotation angle for y-axis labels.
- ylabel_rotation:
- annot:
bool, default=False Add values to each cell.
- annot:
- annot_kws:
dict, default=None, Customize the annotations.
- annot_kws:
- fmt:
str, default=".2g", Modify how the annotated vales are presented.
- fmt:
- linewidths:
float, default=0 Padding between each cell in the plot.
- linewidths:
- borderwidths:
float, default=0 Width of the border around the plot.
- borderwidths:
- linecolor:
str, default="black" Color of the line that seperates each cell.
- linecolor:
- edgecolors:
strorNone, default=None Color of the edges.
- edgecolors:
- alpha:
floatorNone, default=None Controls transparency and ranges from 0 (transparent) to 1 (opaque).
- alpha:
- bbox_inches:
strorNone, default="tight" Alters size of the whitespace in the saved image.
- bbox_inches:
- cmap:
str,callabledefault="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_palettefunction to generate custom palettes.matplotlib.color.LinearSegmentedColormapto generate custom palettes.
- cmap:
- vmin:
floatorNone, default=None The minimum value to display in colormap.
- vmin:
- vmax:
floatorNone, default=None The maximum value to display in colormap.
- vmax:
- 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_file_name=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
CAPclass 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_title (
strorNone, default=None) -- Appended to the name of the saved file.fwhm (
floatorNone, default=None) -- Strength of spatial smoothing to apply (in millimeters) to the statistical map prior to interpolating from MNI152 space to fslr surface space. Usesnilearn.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, 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_fslrfor coordinate system transformation and surfplot'sPlotfor plotting. If CAPs where already converted to NifTI (self.caps2niftis) and transformed to fsLR GifTI files externally, these can be provided using thefslr_giftis_dictparameter and will be converted to a suitable format for surfplot'sPlotfunction by using neuromap'stransforms.fslr_to_fslrfunction. Note, if groups were given when theCAPclass was initialized, surface plots will be generated per CAP for all groups.- Parameters:
output_dir (
os.PathLikeorNone, 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 (
strorNone, default=None) -- Appended to the title of each plot as well as the name of the saved file ifoutput_diris provided.show_figs (
bool, default=True) -- Display figures.fwhm (
floatorNone, 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'simage.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_dictoptions 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_diris provided.Changed in version 0.16.0: changed from
save_stat_maptosave_stat_maps.fslr_giftis_dict (
dictorNone, 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.
- dpi:
- title_pad:
int, default=-3 Padding for the plot title.
- title_pad:
- cmap:
strorcallable, 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_dfuction.matplotlib.colors.LinearSegmentedColormapto generate custom colormaps.
- cmap:
- cbar_kws:
dict, default={"location": "bottom", "n_ticks": 3} Customize colorbar. Refer to
_add_colorbarsat for valid kwargs insurfplot.plotting.Plotdocumentation listed in the Note section.
- cbar_kws:
- alpha:
float, default=1 Transparency level of the colorbar.
- alpha:
- outline_alpha:
float, default=1 Transparency level of the colorbar for outline if
as_outlineis True.
- outline_alpha:
- zero_transparent:
bool, default=True Turns vertices with a value of 0 transparent.
- zero_transparent:
- as_outline:
bool, default=False Plots only an outline of contiguous vertices with the same value.
- as_outline:
- size:
tuple, default=(500, 400) Size of the plot in pixels.
- size:
- layout:
str, default="grid" Layout of the plot.
- layout:
- zoom:
float, default=1.5 Zoom level for the plot.
- zoom:
- views: {"lateral", "medial"} or
list[{"lateral", "medial}], default=["lateral", "medial"] Views to be displayed in the plot.
- views: {"lateral", "medial"} or
- brightness:
float, default=0.5 Brightness level of the plot.
- brightness:
- figsize:
tupleorNone, default=None Size of the figure.
- figsize:
- scale:
tuple, default=(2, 2) Scale factors for the plot.
- scale:
- surface: {"inflated", "veryinflated"}, default="inflated"
The surface atlas that is used for plotting. Options are "inflated" or "veryinflated".
- color_range:
tupleorNone, 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.
- color_range:
- bbox_inches:
strorNone, default="tight" Alters size of the whitespace in the saved image.
- bbox_inches:
- Returns:
NifTI1Image -- NifTI statistical map.
surfplot.plotting.Plot -- An instance of surfplot.plotting.Plot.
Note
Parcellation Approach:
parcel_approachmust 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, 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:
Extract Cluster Centroids:
Each CAP is represented by a cluster centroid, which is a 1 x ROI (Region of Interest) vector.
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])
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)
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)
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
CAPclass was initialized, separate radar plots will be generated per CAP for all groups.- Parameters:
output_dir (
os.PathLikeorNone, 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 (
strorNone, default=None) -- Appended to the title of each plot as well as the name of the saved file ifoutput_diris provided.show_figs (
bool, default=True) -- Display figures. If this function detects that it is not being ran in an interactive Python environment, then it usesplotly.offline, creates an html file named "temp-plot.html", and opens each plot in the default browser.use_scatterpolar (
bool, default=False) -- Usesplotly.graph_objects.Scatterpolarinstead ofplotly.express.line_polar. The primary difference is thatplotly.graph_objects.Scatterpolarshows the scatter dots. However, this can be acheived withplotly.express.line_polarby settingmodeto "markers+lines". There also seems to be a difference in default opacity behavior.as_html (
bool, default=False) -- Whenoutput_diris 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_dirprovided, controls resolution of image when saving. Serves a similar purpose as dpi.
- scale:
- savefig_options:
dict[str], default={"width": 3, "height": 3, "scale": 1} If
output_dirprovided, controls the width (in inches), height (in inches), and scale of the plot. The height and width are multiplied by the dpi.
- savefig_options:
- height:
int, default=800 Height of the plot. Value is multiplied by the dpi when saving.
- height:
- width:
int, defualt=1200 Width of the plot. Value is multiplied by the dpi when saving.
- width:
- line_close:
bool, default=True Whether to close the lines
- line_close:
- bgcolor:
str, default="white" Color of the background
- bgcolor:
- scattersize:
int, default=8 Controls size of the dots when markers are used.
- scattersize:
- connectgaps:
bool, default=True If
use_scatterpolar=True, controls if missing values are connected.
- connectgaps:
- linewidth:
int, default = 2 The width of the line connecting the values if
use_scatterpolar=True.
- linewidth:
- opacity:
float, default=0.5, If
use_scatterpolar=True, sets the opacity of the trace.
- opacity:
- fill:
str, default="none". If "toself" the are of the dots and within the boundaries of the line will be filled.
- fill:
- mode:
str, default="markers+lines", Determines how the trace is drawn. Can include "lines", "markers", "lines+markers", "lines+markers+text".
- mode:
- 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.
- radialaxis:
- 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.
- angularaxis:
- 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.
- color_discrete_map:
- title_font:
dict, default={"family": "Times New Roman", "size": 30, "color": "black"} Modifies the font of the title.
- title_font:
- title_x:
float, default=0.5 Modifies x position of title.
- title_x:
- title_y:
float, default=None Modifies y position of title.
- title_y:
- 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.
- 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_approachthe "regions" sub-key is required.Tick Values: if the
tickvalsorrangesub-keys in this code are not specified in theradialaxiskwarg, 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
radialaxisrefer 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
angularaxisrefer 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
legendandtitle_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