Note
Go to the end to download the full example code.
Animating drifter trajectories#
Trajan supports animating trajectory datasets using a builder pattern.
Start with ds.traj.animate(), chain configuration methods, then call
.show() to display interactively or .save() to write a file.
import logging
import lzma
import numpy as np
import xarray as xr
import coloredlogs
import trajan as ta
coloredlogs.install(level=logging.DEBUG, logger=logging.getLogger('trajan'))
Load the Barents Sea drifter dataset, drop short gaps and grid to 6-hourly.
2026-06-04 11:23:58 runnervm3jyl0 h5py._conv[2854] DEBUG Creating converter from 7 to 5
2026-06-04 11:23:58 runnervm3jyl0 h5py._conv[2854] DEBUG Creating converter from 5 to 7
2026-06-04 11:23:58 runnervm3jyl0 h5py._conv[2854] DEBUG Creating converter from 7 to 5
2026-06-04 11:23:58 runnervm3jyl0 h5py._conv[2854] DEBUG Creating converter from 5 to 7
2026-06-04 11:23:58 runnervm3jyl0 h5py._conv[2854] DEBUG Creating converter from 3 to 5
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detecting trajectory dimension
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detecting time-variable for "obs"..
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detected obs-dim: obs, detected time-variable: time.
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detected un-structured (2D) trajectory dataset
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detecting trajectory dimension
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detecting time-variable for "obs"..
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detected obs-dim: obs, detected time-variable: time.
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detected un-structured (2D) trajectory dataset
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detecting trajectory dimension
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detecting time-variable for "obs"..
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detected obs-dim: obs, detected time-variable: time.
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detected un-structured (2D) trajectory dataset
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detecting trajectory dimension
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detected obs-dim: time, detected time-variable: time.
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detected structured (1D) trajectory dataset
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detecting trajectory dimension
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detecting time-variable for "obs"..
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detected obs-dim: obs, detected time-variable: time.
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detected un-structured (2D) trajectory dataset
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detecting trajectory dimension
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detected obs-dim: time, detected time-variable: time.
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detected structured (1D) trajectory dataset
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detecting trajectory dimension
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detected obs-dim: time, detected time-variable: time.
2026-06-04 11:23:58 runnervm3jyl0 trajan.accessor[2854] DEBUG Detected structured (1D) trajectory dataset
Basic animation — just call .animate() and .show().
The title shows the current timestamp automatically.
ds.traj.animate().set_title('Barents Sea drifters').show()

2026-06-04 11:23:58 runnervm3jyl0 trajan.traj[2854] DEBUG Setting up new plot object.
2026-06-04 11:23:58 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:23:58 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:23:58 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:23:58 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:23:58 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:23:58 runnervm3jyl0 trajan.plot[2854] DEBUG Creating new figure and axes..
2026-06-04 11:23:58 runnervm3jyl0 trajan.animation[2854] DEBUG Dataset is already regularly gridded, skipping gridtime
2026-06-04 11:23:58 runnervm3jyl0 trajan.animation[2854] DEBUG Building animation: 192 frames
2026-06-04 11:23:58 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:23:58 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:23:58 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
/home/runner/micromamba/envs/trajan/lib/python3.14/site-packages/matplotlib/animation.py:908: UserWarning: Animation was deleted without rendering anything. This is most likely not intended. To prevent deletion, assign the Animation to a variable, e.g. `anim`, that exists until you output the Animation using `plt.show()` or `anim.save()`.
warnings.warn(
Colour particles by drift speed.
Pass the DataArray directly to color_by — no need to add it to the dataset.

2026-06-04 11:25:47 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:25:47 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:25:47 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:25:47 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:25:47 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:25:47 runnervm3jyl0 trajan.plot[2854] DEBUG Creating new figure and axes..
2026-06-04 11:25:47 runnervm3jyl0 trajan.animation[2854] DEBUG Dataset is already regularly gridded, skipping gridtime
2026-06-04 11:25:47 runnervm3jyl0 trajan.animation[2854] DEBUG Building animation: 192 frames
2026-06-04 11:25:47 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:25:47 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:25:47 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:25:47 runnervm3jyl0 matplotlib.colorbar[2854] DEBUG locator: <matplotlib.ticker.AutoLocator object at 0x7fb9464ce2a0>
/home/runner/micromamba/envs/trajan/lib/python3.14/site-packages/matplotlib/animation.py:908: UserWarning: Animation was deleted without rendering anything. This is most likely not intended. To prevent deletion, assign the Animation to a variable, e.g. `anim`, that exists until you output the Animation using `plt.show()` or `anim.save()`.
warnings.warn(
Show static trajectory lines in the background so the full path of each drifter is always visible.

2026-06-04 11:27:40 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:27:40 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:27:40 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:27:40 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:27:40 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:27:40 runnervm3jyl0 trajan.plot[2854] DEBUG Creating new figure and axes..
2026-06-04 11:27:40 runnervm3jyl0 trajan.animation[2854] DEBUG Dataset is already regularly gridded, skipping gridtime
2026-06-04 11:27:40 runnervm3jyl0 trajan.animation[2854] DEBUG Building animation: 192 frames
2026-06-04 11:27:40 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:27:40 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:27:40 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:27:40 runnervm3jyl0 trajan.plot[2854] DEBUG Plotting lines
2026-06-04 11:27:40 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:27:40 runnervm3jyl0 trajan.plot[2854] DEBUG axes already set up
2026-06-04 11:27:40 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:27:40 runnervm3jyl0 trajan.traj[2854] DEBUG No grid-mapping specified, checking if coordinates are lon/lat..
2026-06-04 11:27:40 runnervm3jyl0 matplotlib.colorbar[2854] DEBUG locator: <matplotlib.ticker.AutoLocator object at 0x7fb96bbd5010>
/home/runner/micromamba/envs/trajan/lib/python3.14/site-packages/matplotlib/animation.py:908: UserWarning: Animation was deleted without rendering anything. This is most likely not intended. To prevent deletion, assign the Animation to a variable, e.g. `anim`, that exists until you output the Animation using `plt.show()` or `anim.save()`.
warnings.warn(