Skip to content

Examples

This page provides practical examples for common tasks with sleap-io. Each example includes working code that you can copy and adapt for your needs.

Prerequisites

All examples assume you have sleap-io installed:

pip install sleap-io

Or run any example script directly with uv:

# Save any example to a file (e.g., example.py)
uv run --with sleap-io example.py

This automatically handles dependencies without needing to manage environments.

Most examples use import sleap_io as sio for brevity.

Basic I/O operations

Load and save in different formats

Convert between supported formats with automatic format detection.

format_conversion.py
import sleap_io as sio

# Load from SLEAP file
labels = sio.load_file("predictions.slp")

# Save to NWB file
labels.save("predictions.nwb")

Tip

sleap-io automatically detects the format from the file extension. Supported formats include .slp, .nwb, .labelstudio.json, and .jabs.

See also

  • Labels.save: Save method with format options
  • Formats: Complete list of supported formats

Convert labels to raw arrays

Extract pose data as NumPy arrays for analysis or visualization.

labels_to_numpy.py
import sleap_io as sio

labels = sio.load_slp("tests/data/slp/centered_pair_predictions.slp")

# Convert predictions to point coordinates in a single array
trx = labels.numpy()
n_frames, n_tracks, n_nodes, xy = trx.shape
assert xy == 2  # x and y coordinates

# Convert to array with confidence scores appended
trx_with_scores = labels.numpy(return_confidence=True)
n_frames, n_tracks, n_nodes, xy_score = trx_with_scores.shape 
assert xy_score == 3  # x, y, and confidence score
Expected output shapes

For a dataset with 100 frames, 2 tracks, and 3 nodes:

  • Without scores: (100, 2, 3, 2)
  • With scores: (100, 2, 3, 3)

See also

Labels.numpy: Full documentation of array conversion options

Video operations

Read video data

Load and access video frames directly.

read_video.py
import sleap_io as sio

video = sio.load_video("test.mp4")
n_frames, height, width, channels = video.shape

frame = video[0]  # Get first frame
height, width, channels = frame.shape

# Access specific frames
middle_frame = video[n_frames // 2]
last_frame = video[-1]

Info

Video loading uses imageio-ffmpeg by default. For alternative backends, install optional dependencies:

pip install sleap-io[opencv]  # OpenCV backend
pip install sleap-io[pyav]    # PyAV backend  
pip install sleap-io[all]     # All backends

See also

Re-encode video

Fix video seeking issues by re-encoding with optimal settings.

reencode_video.py
import sleap_io as sio

sio.save_video(sio.load_video("input.mp4"), "output.mp4")

Why re-encode?

Some video formats are not readily seekable at frame-level accuracy. Re-encoding with default settings ensures reliable seeking with minimal quality loss.

See also

save_video: Video saving options and codec settings

Trim labels and video

Extract a subset of frames with corresponding labels.

trim_video.py
import sleap_io as sio

# Load existing data
labels = sio.load_file("labels.slp")

# Create a new labels file with frames 1000-2000 from video 0
clip = labels.trim("clip.slp", list(range(1_000, 2_000)), video=0)

# The new file contains:
# - A trimmed video saved as "clip.mp4"
# - Labels with adjusted frame indices

Tip

The trim method automatically:

  • Creates a new video file with only the specified frames
  • Adjusts frame indices in the labels to match the new video
  • Preserves all instance data and tracks

See also

Labels.trim: Full trim method documentation

Data creation

Create labels from raw data

Build a complete labels dataset programmatically.

create_labels.py
import sleap_io as sio
import numpy as np

# Create skeleton
skeleton = sio.Skeleton(
    nodes=["head", "thorax", "abdomen"],
    edges=[("head", "thorax"), ("thorax", "abdomen")]
)

# Create video
video = sio.load_video("test.mp4")

# Create instance from numpy array
instance = sio.Instance.from_numpy(
    points=np.array([
        [10.2, 20.4],  # head
        [5.8, 15.1],   # thorax
        [0.3, 10.6],   # abdomen
    ]),
    skeleton=skeleton
)

# Create labeled frame
lf = sio.LabeledFrame(video=video, frame_idx=0, instances=[instance])

# Create labels
labels = sio.Labels(videos=[video], skeletons=[skeleton], labeled_frames=[lf])

# Save
labels.save("labels.slp")
Creating predicted instances

To create predictions with confidence scores:

predicted_instance = sio.PredictedInstance.from_numpy(
    points=points_array,
    confidence=confidence_array,  # Shape: (n_nodes,)
    skeleton=skeleton
)

See also

Dataset management

Make training/validation/test splits

Split your dataset for machine learning workflows.

make_splits.py
import sleap_io as sio

# Load source labels
labels = sio.load_file("labels.v001.slp")

# Make splits and export with embedded images
labels.make_training_splits(
    n_train=0.8, 
    n_val=0.1, 
    n_test=0.1, 
    save_dir="split1", 
    seed=42
)

# Splits are saved as self-contained SLP package files
labels_train = sio.load_file("split1/train.pkg.slp")
labels_val = sio.load_file("split1/val.pkg.slp")
labels_test = sio.load_file("split1/test.pkg.slp")

Info

The .pkg.slp extension indicates a self-contained package with embedded images, making the splits portable and shareable.

See also

Labels.make_training_splits: Full documentation of splitting options

Working with dataset splits (LabelsSet)

Manage multiple related datasets as a group.

labels_set.py
import sleap_io as sio

# Load source labels
labels = sio.load_file("labels.v001.slp")

# Create splits and get them as a LabelsSet
labels_set = labels.make_training_splits(n_train=0.8, n_val=0.1, n_test=0.1)

# Access individual splits
train_labels = labels_set["train"]
val_labels = labels_set["val"] 
test_labels = labels_set["test"]

# Save the entire LabelsSet
labels_set.save("splits/")  # Saves as SLP files by default

# Save as Ultralytics YOLO format
labels_set.save("yolo_dataset/", format="ultralytics")

# Load a LabelsSet from a directory
loaded_set = sio.load_labels_set("splits/")
Loading from specific files
# Load from custom file paths
file_dict = {
    "train": "path/to/train.slp",
    "val": "path/to/val.slp",
    "test": "path/to/test.slp"
}
loaded_set = sio.load_labels_set(file_dict)

Tip

LabelsSet is particularly useful when exporting to formats that expect separate train/val/test files, like YOLO.

See also

Data manipulation

Fix video paths

Update file paths when moving projects between systems.

fix_paths.py
import sleap_io as sio

# Load labels without trying to open the video files
labels = sio.load_file("labels.v001.slp", open_videos=False)

# Fix paths using prefix replacement
labels.replace_filenames(prefix_map={
    "D:/data/sleap_projects": "/home/user/sleap_projects",
    "C:/Users/sleaper/Desktop/test": "/home/user/sleap_projects",
})

# Save labels with updated paths
labels.save("labels.v002.slp")

Path separators

The prefix map handles path separators automatically, but be consistent with forward slashes (/) for cross-platform compatibility.

Tip

Use open_videos=False when loading to avoid errors from missing videos at the old paths.

See also

Labels.replace_filenames: Additional path manipulation options

Save labels with embedded images

Create self-contained label files with embedded video frames.

embed_images.py
import sleap_io as sio

# Load source labels
labels = sio.load_file("labels.v001.slp")

# Save with embedded images for frames with user labeled data and suggested frames
labels.save("labels.v001.pkg.slp", embed="user+suggestions")

Embedding options

  • "user": Only frames with manual annotations
  • "user+suggestions": Manual annotations plus suggested frames
  • "all": All frames with any labels (including predictions)
  • "source": Embed source video if labels were loaded from embedded data

See also

Labels.save: Complete save options including embedding

Replace skeleton

Change the skeleton structure while preserving existing annotations.

replace_skeleton.py
import sleap_io as sio

# Load existing labels with skeleton nodes: "head", "trunk", "tti"
labels = sio.load_file("labels.slp")

# Create a new skeleton with different nodes
new_skeleton = sio.Skeleton(["HEAD", "CENTROID", "TAIL_BASE", "TAIL_TIP"])

# Replace skeleton with node correspondence mapping
labels.replace_skeleton(
    new_skeleton,
    node_map={
        "head": "HEAD",
        "trunk": "CENTROID",
        "tti": "TAIL_BASE"
        # "TAIL_TIP" will have NaN values since there's no correspondence
    }
)

# Save with the new skeleton format
labels.save("labels_with_new_skeleton.slp")

Warning

Nodes without correspondence in the node_map will have NaN values in the resulting instances.

Tip

This is particularly useful when converting between different annotation tools or skeleton conventions.

See also

Labels.replace_skeleton: Additional skeleton manipulation options

Convert to and from numpy arrays

Work with pose data as NumPy arrays for filtering or analysis.

numpy_filtering.py
import sleap_io as sio
import numpy as np

labels = sio.load_file("predictions.slp")

# Convert to array of shape (n_frames, n_tracks, n_nodes, xy)
trx = labels.numpy()

# Apply temporal filtering (example: simple moving average)
window_size = 5
trx_filtered = np.convolve(trx.reshape(-1), np.ones(window_size)/window_size, mode='same').reshape(trx.shape)

# Update the labels with filtered data
labels.update_from_numpy(trx_filtered)

# Save the filtered version
labels.save("predictions.filtered.slp")
Advanced filtering with movement

For more sophisticated analysis and filtering, check out the movement library for pose processing.

Warning

When updating from numpy, the array shape must match the original data structure exactly.

See also