How to Animate the Morphing Process¶
carto-flow can create animations that show the geometry evolving from original to cartogram over the course of the algorithm's iterations. This is useful for presentations and for understanding how the morphing algorithm works.
Requirements: To animate the morph process, you need to capture intermediate frames by setting snapshot_every in MorphOptions. To animate the internal density and velocity fields, you need to capture these by setting save_internals=True in MorphOptions.
import matplotlib.pyplot as plt
from IPython.display import HTML
from matplotlib import rc
import carto_flow.data as examples
import carto_flow.flow_cartogram as flow
from carto_flow.flow_cartogram.animation import animate_morph_history, save_animation
Step 1: Morph with snapshot capture¶
Set snapshot_every=N to save a geometry snapshot every N iterations. This adds a small overhead but enables the animation.
gdf = examples.load_us_census(population=True)
cartogram = flow.morph_gdf(
gdf,
"Population",
options=flow.MorphOptions.preset_balanced().copy_with(
n_iter=250,
snapshot_every=5,
area_scale=1e-6,
save_internals=True,
),
)
print(f"Captured {len(cartogram.snapshots)} snapshots")
Morph geometries: 45%|███████████████▋ | 112/250 [00:05<00:07, 19.38it/s, max=1.2%, mean=0.2% - converged]
Captured 24 snapshots
Step 2: Build the animation¶
animate_morph_history() returns a matplotlib FuncAnimation. You can display it inline in a notebook or save it to a file.
anim = animate_morph_history(
cartogram,
duration=2.0, # total animation length in seconds
fps=15,
color_by="errors_pct",
cmap="PiYG",
figsize=(8, 5),
show_axes=False,
colorbar=True,
vmin=-1000,
vmax=1000,
linewidth=0.5,
edgecolor="black",
title="iteration {iteration:.1f} | error = {mean_error_pct:.1f}%",
)
plt.close()
# Display inline
rc("animation", html="jshtml")
HTML(anim.to_jshtml())
Step 3: Save to file¶
save_animation() writes a GIF (requires Pillow) or MP4 (requires ffmpeg). GIF is the simplest option and works without extra dependencies.
# Save as GIF
save_animation(anim, "cartogram_morph.gif", fps=15)
# Or as MP4 (requires ffmpeg)
# save_animation(anim, 'cartogram_morph.mp4', fps=15)
Animate Density Field¶
anim = flow.animation.animate_density_field(
cartogram,
duration=2.0,
fps=15,
show_axes=False,
figsize=(8, 5),
density=flow.DensityPlotOptions(
colorbar_kwargs={"shrink": 0.7},
normalize="ratio",
),
)
plt.close()
# Display inline
rc("animation", html="jshtml")
HTML(anim.to_jshtml())
Animate Velocity Field¶
anim = flow.animation.animate_velocity_field(
cartogram,
duration=2.0,
fps=15,
show_axes=False,
figsize=(8, 5),
velocity=flow.VelocityPlotOptions(colorbar_kwargs={"shrink": 0.7}, color_by="direction", velocity_scale=3),
)
plt.close()
# Display inline
rc("animation", html="jshtml")
HTML(anim.to_jshtml())