Note
Go to the end to download the full example code. or to run this example in your browser via Binder
Using brain templates from TemplateFlow¶
In this example, we see how to fetch and use brain templates from TemplateFlow.
We first see how to fetch and use the Desikan-Killiany (DK) atlas in order to make surface plots.
Then, we see how to get the proper template for the Harvard-Oxford volumetric atlas.
Datasets used in this example
Fetch DK Surface template¶
TemplateFlow allows for the retrieval of image files, annotations, and
metadata for various brain templates.
Specific files are accessed via the get function
by providing the template name
and filtering by file name ‘entities’
such as resolution (res),
suffix, atlas, hemisphere (hemi), space,
description (desc)…
Tips
TemplateFlow files follow a BIDS filename template and should more less be organized as BIDS template.
If a search matches multiple files, the function returns a list of all matching paths.
Available resources can be explored in the TemplateFlow browser.
import templateflow.api as tflow
from nilearn.surface import SurfaceImage, load_surf_data
template = "fsaverage"
fetched_files = tflow.get(
template,
extension="surf.gii",
suffix="pial",
)
print(fetched_files)
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-L_den-3k_pial.surf.gii
0%| | 0.00/66.1k [00:00<?, ?B/s]
100%|██████████| 66.1k/66.1k [00:00<00:00, 993kB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-L_den-10k_pial.surf.gii
0%| | 0.00/271k [00:00<?, ?B/s]
26%|██▌ | 69.6k/271k [00:00<00:00, 533kB/s]
100%|██████████| 271k/271k [00:00<00:00, 1.37MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-L_den-41k_pial.surf.gii
0%| | 0.00/1.07M [00:00<?, ?B/s]
7%|▋ | 69.6k/1.07M [00:00<00:01, 533kB/s]
37%|███▋ | 400k/1.07M [00:00<00:00, 1.70MB/s]
100%|██████████| 1.07M/1.07M [00:00<00:00, 3.22MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-L_den-164k_pial.surf.gii
0%| | 0.00/4.34M [00:00<?, ?B/s]
2%|▏ | 69.6k/4.34M [00:00<00:07, 554kB/s]
9%|▉ | 383k/4.34M [00:00<00:02, 1.68MB/s]
28%|██▊ | 1.22M/4.34M [00:00<00:00, 3.93MB/s]
86%|████████▌ | 3.72M/4.34M [00:00<00:00, 10.2MB/s]
100%|██████████| 4.34M/4.34M [00:00<00:00, 8.46MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-R_den-3k_pial.surf.gii
0%| | 0.00/66.1k [00:00<?, ?B/s]
100%|██████████| 66.1k/66.1k [00:00<00:00, 1.00MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-R_den-10k_pial.surf.gii
0%| | 0.00/271k [00:00<?, ?B/s]
26%|██▋ | 71.7k/271k [00:00<00:00, 548kB/s]
100%|██████████| 271k/271k [00:00<00:00, 1.36MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-R_den-41k_pial.surf.gii
0%| | 0.00/1.07M [00:00<?, ?B/s]
7%|▋ | 71.7k/1.07M [00:00<00:01, 569kB/s]
36%|███▌ | 385k/1.07M [00:00<00:00, 1.88MB/s]
100%|██████████| 1.07M/1.07M [00:00<00:00, 3.34MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-R_den-164k_pial.surf.gii
0%| | 0.00/4.34M [00:00<?, ?B/s]
2%|▏ | 69.6k/4.34M [00:00<00:08, 528kB/s]
8%|▊ | 366k/4.34M [00:00<00:02, 1.53MB/s]
32%|███▏ | 1.41M/4.34M [00:00<00:00, 4.42MB/s]
100%|██████████| 4.34M/4.34M [00:00<00:00, 9.05MB/s]
[PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-L_den-3k_pial.surf.gii'), PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-L_den-10k_pial.surf.gii'), PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-L_den-41k_pial.surf.gii'), PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-L_den-164k_pial.surf.gii'), PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-R_den-3k_pial.surf.gii'), PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-R_den-10k_pial.surf.gii'), PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-R_den-41k_pial.surf.gii'), PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-R_den-164k_pial.surf.gii')]
In this example, the Desikan-Killiany (DK) atlas is fetched. DK is defined with reference to the FreeSurfer average (fsaverage) template, which is provided at multiple densities (number of vertices per hemisphere): 3k, 10k, 41k, 164k Here, we build a SurfaceImage containing the labels for both hemispheres for the 3k and 10k densities.
used_densities = ["3k", "10k"]
# uncomment the following line in case you want to see all densities
# used_densities = ["3k", "10k", "41k", "164k"]
desikan_dict = {}
for density in ["3k", "10k"]:
mesh = {}
data = {}
for hemi in ["left", "right"]:
mesh[hemi] = tflow.get(
template,
extension="surf.gii",
suffix="pial",
density=density,
hemi=hemi[0].upper(),
)
desc = "curated" if density == "164k" else None
roi_data = load_surf_data(
tflow.get(
template,
atlas="Desikan2006",
density=density,
hemi=hemi[0].upper(),
extension="label.gii",
desc=desc,
)
)
if density == "164k":
roi_data[roi_data < 0] = 0
data[hemi] = roi_data
desikan_dict[density] = SurfaceImage(mesh=mesh, data=data)
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-L_den-3k_atlas-Desikan2006_seg-aparc_dseg.label.gii
0%| | 0.00/6.79k [00:00<?, ?B/s]
100%|██████████| 6.79k/6.79k [00:00<00:00, 11.7MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-R_den-3k_atlas-Desikan2006_seg-aparc_dseg.label.gii
0%| | 0.00/6.79k [00:00<?, ?B/s]
100%|██████████| 6.79k/6.79k [00:00<00:00, 20.2MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-L_den-10k_atlas-Desikan2006_seg-aparc_dseg.label.gii
0%| | 0.00/9.61k [00:00<?, ?B/s]
100%|██████████| 9.61k/9.61k [00:00<00:00, 25.3MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-R_den-10k_atlas-Desikan2006_seg-aparc_dseg.label.gii
0%| | 0.00/9.52k [00:00<?, ?B/s]
100%|██████████| 9.52k/9.52k [00:00<00:00, 25.1MB/s]
Plotting the DK atlas¶
To plot the DK atlas, we also fetch the lookup table (LUT) from TemplateFlow, to map region indices to the original region names and colors. We also use the background sulcal depth map to add more detail to the surface plot. To do this we map the density to the corresponding fsaverage data that Nilearn can fetch directly.
import matplotlib.pyplot as plt
from nilearn.datasets import load_fsaverage_data
from nilearn.plotting import plot_surf_roi, show
_, axes = plt.subplots(1, 2, subplot_kw={"projection": "3d"})
fs_density = {
"3k": "fsaverage4",
"10k": "fsaverage5",
"41k": "fsaverage6",
"164k": "fsaverage",
}
lut = tflow.get(
template,
atlas="Desikan2006",
suffix="dseg",
extension="tsv",
)
for ax, density in zip(axes, ["3k", "10k"], strict=True):
desikan = desikan_dict[density]
sulcal_depth_map = load_fsaverage_data(
mesh=fs_density[density], data_type="sulcal"
)
plot_surf_roi(
roi_map=desikan,
cmap=lut,
bg_map=sulcal_depth_map,
bg_on_data=True,
title=f"DK atlas ({density})",
axes=ax,
)
if density == "10k":
ax._colorbars[0].remove()
show()

[load_fsaverage_data] Dataset created in /home/runner/nilearn_data/fsaverage4
[load_fsaverage_data] Downloading data from https://osf.io/28uma/download ...
[load_fsaverage_data] ...done. (3 seconds, 0 min)
[load_fsaverage_data] Extracting data from /home/runner/nilearn_data/fsaverage4/
8d2777113299ca7de61b16037c37aaea/download...
[load_fsaverage_data] .. done.
[load_fsaverage_data] Dataset found in /home/runner/nilearn_data/fsaverage4
Getting the right template for volumetric atlases¶
The template used by nilearn to plot volumetric images is ICBM152 2009, release a. However, some atlases are defined on different templates, this is the case for the Harvard-Oxford atlas. This can lead to some imprecisions when plotting volumetric atlases, with regions encompassing non-brain areas.
from nilearn.datasets import fetch_atlas_harvard_oxford
from nilearn.plotting import plot_roi
plotting_params = {
"view_type": "contours",
"display_mode": "x",
"cut_coords": [-4, -2, 0],
"black_bg": False,
}
harvard_oxford_sub = fetch_atlas_harvard_oxford("sub-maxprob-thr25-1mm")
plot_roi(
harvard_oxford_sub.filename,
title="Harvard-Oxford atlas | sub-cortical | ICBM152 2009",
**plotting_params,
)

[fetch_atlas_harvard_oxford] Dataset found in /home/runner/nilearn_data/fsl
<nilearn.plotting.displays._slicers.XSlicer object at 0x7fc317bca110>
This is because the template of the Harvard-Oxford atlas is:
print(f"Harvard-Oxford atlas template: {harvard_oxford_sub.template}")
Harvard-Oxford atlas template: MNI152NLin6Asym
Getting a template¶
If you want to visualize the Harvard-Oxford atlas on the template it was originally defined, you can get it from TemplateFlow. This template is the default template used by FSL, and its unique identifier within TemplateFlow is`MNI152NLin6Asym`.
template = "MNI152NLin6Asym"
resolution = "01"
MNI152NLin6Asym_template_img = tflow.get(
template,
resolution=resolution,
suffix="T1w",
desc="brain", # Set desc-brain to get the skull-stripped variant
extension="nii.gz",
)
print(f"{MNI152NLin6Asym_template_img=}")
plot_roi(
harvard_oxford_sub.filename,
title="Harvard-Oxford atlas | sub-cortical | MNI152NLin6Asym",
bg_img=MNI152NLin6Asym_template_img,
**plotting_params,
)
show()

Downloading https://templateflow.s3.amazonaws.com/tpl-MNI152NLin6Asym/tpl-MNI152NLin6Asym_res-01_desc-brain_T1w.nii.gz
0%| | 0.00/3.29M [00:00<?, ?B/s]
2%|▏ | 69.6k/3.29M [00:00<00:05, 538kB/s]
12%|█▏ | 400k/3.29M [00:00<00:01, 1.70MB/s]
52%|█████▏ | 1.70M/3.29M [00:00<00:00, 5.46MB/s]
100%|██████████| 3.29M/3.29M [00:00<00:00, 8.03MB/s]
MNI152NLin6Asym_template_img=PosixPath('/home/runner/.cache/templateflow/tpl-MNI152NLin6Asym/tpl-MNI152NLin6Asym_res-01_desc-brain_T1w.nii.gz')
Total running time of the script: (0 minutes 25.266 seconds)
Estimated memory usage: 187 MB