Note
Go to the end to download the full example code.
Create a GIF Movie of a Static Object with a Moving Colormap#
Generate a gif movie of a Hopf torus with a moving colormap, by updating the scalars.
from __future__ import annotations
import numpy as np
import pyvista as pv
# A spherical curve
def scurve(t):
alpha = np.pi / 2 - (np.pi / 2 - 0.44) * np.cos(3 * t)
beta = t + 0.44 * np.sin(6 * t)
return np.array([np.sin(alpha) * np.cos(beta), np.sin(alpha) * np.sin(beta), np.cos(alpha)])
# Hopf fiber
def hopf_fiber(p, phi):
return np.array(
[
(1 + p[2]) * np.cos(phi),
p[0] * np.sin(phi) - p[1] * np.cos(phi),
p[0] * np.cos(phi) + p[1] * np.sin(phi),
(1 + p[2]) * np.sin(phi),
],
) / np.sqrt(2 * (1 + p[2]))
# Stereographic projection
def stereo_proj(q):
return q[0:3] / (1 - q[3])
# Parameterization of the Hopf torus
def hopf_torus(t, phi):
return stereo_proj(hopf_fiber(scurve(t), phi))
# Create the mesh
angle_u = np.linspace(-np.pi, np.pi, 400)
angle_v = np.linspace(0, np.pi, 200)
u, v = np.meshgrid(angle_u, angle_v)
x, y, z = hopf_torus(u, v)
grid = pv.StructuredGrid(x, y, z)
mesh = grid.extract_geometry().clean(tolerance=1e-6)
# Distances normalized to [0, 2*pi]
dists = np.linalg.norm(mesh.points, axis=1)
dists = 2 * np.pi * (dists - dists.min()) / (dists.max() - dists.min())
mesh["distances"] = np.sin(dists)
# Make the movie
pltr = pv.Plotter(window_size=[512, 512])
pltr.set_focus([0, 0, 0])
pltr.set_position([40, 0, 0])
pltr.add_mesh(
mesh,
scalars="distances",
smooth_shading=True,
specular=1,
cmap="nipy_spectral",
show_scalar_bar=False,
)
pltr.open_gif("Hopf_torus.gif")
for t in np.linspace(0, 2 * np.pi, 60, endpoint=False):
mesh["distances"] = np.sin(dists - t)
pltr.write_frame()
pltr.show()
Total running time of the script: (0 minutes 10.452 seconds)