SurfacePlot: Basics
This tutorial builds a cortical map with electrode contacts, then shows how to display atlas labels on the same surfaces.
1. Fetch matching surfaces and shading
Fetch public fsLR 32k inflated surfaces for the visible brain and sulcal depth from the same template and density for its shading. More built-in templates and atlases are listed in Datasets.
import numpy as np
from anatplot import SurfacePlot, datasets
surfaces = datasets.fetch_surfaces("fsLR", surface="inflated", density="32k")
sulc = datasets.fetch_sulcal_depth("fsLR", density="32k")
2. Add the map
Start with the Neurosynth association map for the “default mode” term, using sulcal shading to make the cortical folds visible.
left_map, right_map = datasets.fetch_dmn_map_fslr32k()
# Mask this map's zero background to leave the shading underneath visible.
association = {
"left": np.ma.masked_equal(left_map, 0),
"right": np.ma.masked_equal(right_map, 0),
}
plot = SurfacePlot(
**surfaces,
views=["lateral", "medial"],
window_size=(1000, 600),
zoom=1.5,
)
plot.add_layer(sulc, cmap="gray") # Sulcal shading beneath the map.
# Give the map its own labelled colorbar.
plot.add_layer(association, cmap="YlOrRd", cbar=True, cbar_label="Association Z")
fig = plot.to_figure(figsize=(10, 7))
3. Add contacts to this map
Next, add four contacts to the map, using color to distinguish the two pairs.
# Coordinates in the template's RAS millimetre frame.
xyz = [
[-64, -13, 23],
[-60, -42, 37],
[66, -14, 22],
[64, -37, 32],
]
plot.add_contacts(
xyz,
radius=4.0,
color=["royalblue", "gold", "royalblue", "gold"],
)
fig = plot.to_figure(figsize=(10, 7))
Contacts on inflated surfaces
Contacts must share the original pial or midthickness surface's RAS
millimetre frame. The projection_surface pair returned by fetch_surfaces()
lets SurfacePlot locate contacts on that anatomy and transfer them to the
inflated display. Projection removes depth and skips contacts farther than
6 mm by default; see contact projection.
4. Save the completed figure
Save the completed figure, then close the scene to release graphics resources.
fig.savefig("cortex.png", dpi=300)
plot.close()
For 3D viewing and HTML export, see Save and display. To substitute your own maps or contacts, see Use your own data.
Alternative: show atlas labels
To show regions instead of a continuous map, use the Schaefer 100-region,
seven-network atlas on the same fsLR 32k surfaces. add_parcellation() assigns
colors to labels without creating a colorbar.
parcellation = datasets.fetch_parcellation("schaefer")
# Hide the atlas background while preserving the original parcel IDs.
labels = {
"left": np.ma.masked_equal(parcellation["left"], 0),
"right": np.ma.masked_equal(parcellation["right"], 0),
}
# A with block releases the scene's graphics resources when it ends.
with SurfacePlot(
**surfaces,
views=["lateral", "medial"],
window_size=(1000, 600),
zoom=1.5,
) as atlas_plot:
atlas_plot.add_layer(sulc, cmap="gray")
atlas_plot.add_parcellation(labels)
atlas_fig = atlas_plot.to_figure(figsize=(10, 7))
Highlight left-hemisphere parcels 17 and 18 while leaving the rest of the cortex visible.
parcellation = datasets.fetch_parcellation("schaefer")
left_labels = parcellation["left"]
# Keep the selected IDs and hide all other parcels with NaN.
selected = np.where(np.isin(left_labels, [17, 18]), left_labels, np.nan)
with SurfacePlot(
**surfaces,
views=["lateral", "medial"],
window_size=(1000, 600),
zoom=1.5,
) as atlas_plot:
atlas_plot.add_layer(sulc, cmap="gray")
atlas_plot.add_parcellation(
{"left": selected},
cmap={17: "crimson", 18: "gold"},
)
atlas_fig = atlas_plot.to_figure(figsize=(10, 7))
Parcel names are available from the atlas label table, for example
parcellation["labels"]["left"][17]["name"].
Brain size and spacing
If the brains in either recipe need more or less room, adjust zoom. Within
one SurfacePlot, layout arranges the views; there is no separate gap
setting.
| Change | Effect |
|---|---|
Increase zoom |
Larger brains, smaller visible gaps |
Decrease zoom |
Smaller brains, larger visible gaps |
Panel positions stay fixed. Excessive zoom can crop a brain, and the
window_size width-to-height ratio also affects space available per view.