Sparse atlases¶
This demo showcases the INIA19 template and atlas for the rhesus monkey. The INIA19 atlas is sparse, containing hundreds of regions distributed across thousands of indices. NiiVue efficiently visualizes this type of atlas using minimal resources, ensuring smooth interactivity even on low-power devices.
This Python script is similar the corresponding JavaScript web demo.
TODO: This notebook will require a new release of ipyniivue to support set_atlas_active_index and update_gl_volume
In [1]:
import json
import ipywidgets as widgets
from IPython.display import display
from ipyniivue import DragMode, NiiVue, ShowRender
# Setup NiiVue Instance
nv = NiiVue(
back_color=(0.5, 0.5, 0.5, 1),
show_3d_crosshair=True,
drag_mode=DragMode.PAN,
yoke_3d_to_2d_zoom=True,
multiplanar_show_render=ShowRender.ALWAYS,
)
nv.load_volumes(
[
{"path": "../images/inia19-t1-brain.nii.gz"},
{"path": "../images/inia19-NeuroMaps.nii.gz", "opacity": 0.5},
]
)
# for urls: nv.volumes[1].set_colormap_label_from_url("./images/inia19-NeuroMaps.json")
with open( "../images/inia19-NeuroMaps.json") as f:
cmap = json.load(f)
nv.volumes[1].set_colormap_label(cmap)
nv.volumes[1].opacity = 0.03
nv.set_atlas_outline(0.01)
## UI
# Slider for opacity
opacity_slider = widgets.IntSlider(
min=1,
max=255,
value=8,
description="Opacity",
continuous_update=True,
readout=False,
)
location_label = widgets.HTML(" ")
outline_options = ["None", "Gap", "Opaque", "Black"]
outline_dropdown = widgets.Dropdown(
options=outline_options,
value="Gap",
description="Atlas outline",
)
render_options = ["Slices", "Matte", "Low", "Medium", "High"]
render_dropdown = widgets.Dropdown(
options=render_options,
value="Matte",
description="Render mode",
style={"description_width": "initial"},
)
## Define callbacks
def on_opacity_change(change):
"""Update the opacity of the atlas volume."""
nv.volumes[1].opacity = change["new"] / 255
def on_outline_change(change):
"""Set atlas outline style."""
value_name = change["new"]
# Default borderValue for "No border"
borderValue = 0.0
if value_name == "Gap":
borderValue = 0.01
elif value_name == "Opaque":
borderValue = 1
elif value_name == "Black":
borderValue = -1.0
# else "None" → 0.0
nv.set_atlas_outline(borderValue)
def on_render_change(change):
"""Set render mode."""
value_name = change["new"]
# Default borderValue for "matte"
renderValue = 0.0
if value_name == "Slices":
renderValue = -1.0
elif value_name == "Low":
renderValue = 0.3
elif value_name == "Medium":
renderValue = 0.6
elif value_name == "High":
renderValue = 1.0
# else "Matte" → 0.0
nv.set_volume_render_illumination(renderValue)
# nv.update_gl_volume()
def handle_location_change(location):
"""Update the location label with current coordinates."""
region = int(location["values"][1]["value"])
if region == nv.opts.atlas_active_index:
return
# nv.set_atlas_active_index(region)
location_label.value = location["string"]
## Setup observers
opacity_slider.observe(on_opacity_change, names="value")
nv.on_location_change(handle_location_change)
on_opacity_change({"new": opacity_slider.value})
outline_dropdown.observe(on_outline_change, names="value")
render_dropdown.observe(on_render_change, names="value")
## Display All
controls = widgets.HBox([opacity_slider, outline_dropdown, render_dropdown])
display(
widgets.VBox(
[
controls,
nv,
location_label,
]
)
)
In [ ]: