✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.

Visualizing MRI Volume Slices in Python

How to create an plotly animation with slider that cycles through MRI cross-sections of a human brain.

Write, deploy, & scale Dash apps and Python data visualizations on a Kubernetes Dash Enterprise cluster.
Get Pricing  |  Demo Dash Enterprise  |  Dash Enterprise Overview

New to Plotly?

Plotly is a free and open-source graphing library for Python. We recommend you read our Getting Started guide for the latest installation or upgrade instructions, then move on to our Plotly Fundamentals tutorials or dive straight in to some Basic Charts tutorials.

Visualization of MRI volume slices

In [1]:
# Import data
import time
import numpy as np

from skimage import io

vol = io.imread("https://s3.amazonaws.com/assets.datacamp.com/blog_assets/attention-mri.tif")
volume = vol.T
r, c = volume[0].shape

# Define frames
import plotly.graph_objects as go
nb_frames = 68

fig = go.Figure(frames=[go.Frame(data=go.Surface(
    z=(6.7 - k * 0.1) * np.ones((r, c)),
    surfacecolor=np.flipud(volume[67 - k]),
    cmin=0, cmax=200
    name=str(k) # you need to name the frame for the animation to behave properly
    for k in range(nb_frames)])

# Add data to be displayed before animation starts
    z=6.7 * np.ones((r, c)),
    cmin=0, cmax=200,
    colorbar=dict(thickness=20, ticklen=4)

def frame_args(duration):
    return {
            "frame": {"duration": duration},
            "mode": "immediate",
            "fromcurrent": True,
            "transition": {"duration": duration, "easing": "linear"},

sliders = [
                "pad": {"b": 10, "t": 60},
                "len": 0.9,
                "x": 0.1,
                "y": 0,
                "steps": [
                        "args": [[f.name], frame_args(0)],
                        "label": str(k),
                        "method": "animate",
                    for k, f in enumerate(fig.frames)

# Layout
         title='Slices in volumetric data',
                    zaxis=dict(range=[-0.1, 6.8], autorange=False),
                    aspectratio=dict(x=1, y=1, z=1),
         updatemenus = [
                "buttons": [
                        "args": [None, frame_args(50)],
                        "label": "▶", # play symbol
                        "method": "animate",
                        "args": [[None], frame_args(0)],
                        "label": "◼", # pause symbol
                        "method": "animate",
                "direction": "left",
                "pad": {"r": 10, "t": 70},
                "type": "buttons",
                "x": 0.1,
                "y": 0,