Hyperanimator

the hypertiling library offers a simple way to animate hyperbolic tilings using the FuncAnimation feature of matplotlib. The hyperanimator class is a wrapper which simplifies the associated syntax and let’s you realize simple animation with very little effort

[1]:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
import matplotlib.cm as cmap
[2]:
from hypertiling import HyperbolicTiling
from hypertiling.neighbors import find
from hypertiling.graphics.plot import convert_polygons_to_patches

enable interactive plot in notebook

[22]:
%matplotlib notebook

define a function which takes one configuration to the next. In this case we implement a simple Ising model

[23]:
J = 1 # coupling constant (positiv: ferromagnet, negativ: antiferromagnet)

def step(state, beta):

    for i in range(len(state)):

        site = np.random.choice(len(state))

        nbrhood = 0
        for n in nbrs[site]:
            nbrhood += state[n]

        phi_old = state[site]
        phi_new = -state[site]
        E1 = -J*phi_old*nbrhood
        E2 = -J*phi_new*nbrhood
        dE = E2-E1

        if dE < 0:
            state[site] = phi_new
        elif np.random.rand() < np.exp(-beta*dE):
            state[site] = phi_new

    return state

construct the tiling

[24]:
T = HyperbolicTiling(3, 7, 6)
nbrs = find(T)
[hypertiling] No search radius given; Assuming lattice spacing of the tessellation!

generate an initial stae

[25]:
colors = 2*np.random.choice(2, len(T))-1

Option 1: Live Animation

[26]:
# import hyperanimator class
from hypertiling.graphics.animator import animate_live

[28]:
# create figure
fig, axs = plt.subplots(1,1,figsize=(7,7))

# plot tiling using built in function "poly2patch"
patchkwargs = {"cmap": cmap.RdYlGn, "edgecolor": "#f1f2f0ff", "lw": 0.7, "clim":[-1.5,1.5]}
pgons = convert_polygons_to_patches(T, colors, **patchkwargs)
axs.add_collection(pgons)

# ------- this is the animation part -------
# note: the argument "frames" is only relevant for saving the animation, in the
# live plot it will run forever (until manually stopped)

# extra arguments to the step functions; leave away if there are none
stepargs = {"beta": 2}
# arguments to be passed through to the matplotlib FuncAnimator
animargs = {"frames": 300, "interval": 5, "blit": True}
# the actual animator
ani = animate_live(colors, fig, pgons, step, stepargs, animargs)
# -------


# some usual plot adjustments
axs.add_patch(plt.Circle((0.0, 0.0), radius=1, edgecolor='k', facecolor='None', zorder=7))
axs.set_xlim(-1.02,1.02)
axs.set_ylim(-1.02,1.02)
axs.axis("off"); axs.set_aspect('equal'); plt.show()

hyperanimations can be easily saved like this

[11]:
ani.save("/home/user/anim.mp4", fps=10, codec="libx264")

Option 2: List Animation

[29]:
from hypertiling.graphics.animator import animate_list

Pre-compute some data and store it in 2D array-like container. Here we use our Ising model, but of course data can come from anywhere

[30]:
# first dimension: max number of frames, second dimension: len(tiling)
colors_list = np.zeros((100,len(T)))

for i in range(100):
    colors_list[i] = step(colors, beta=0.1)
[31]:
# create figure
fig, axs = plt.subplots(1,1,figsize=(7,7))

# plot tiling using built in function "poly2patch"
patchkwargs = {"cmap": cmap.RdYlGn, "edgecolor": "#f1f2f0ff", "lw": 0.7, "clim":[-1.5,1.5]}
pgons = convert_polygons_to_patches(T, colors, **patchkwargs)
axs.add_collection(pgons)

# ------- this is the animation part -------

# arguments to be passed through to the matplotlib FuncAnimator
animargs = {"interval": 200, "blit": True}

# the actual animator
ani = animate_list(colors_list, fig, pgons, animargs)

# -------

# some usual plot adjustments
axs.add_patch(plt.Circle((0.0, 0.0), radius=1, edgecolor='k', facecolor='None', zorder=7))
axs.set_xlim(-1.02,1.02)
axs.set_ylim(-1.02,1.02)
axs.axis("off"); axs.set_aspect('equal'); plt.show()
[ ]:
ani.save("/home/user/anim.mp4", fps=10, codec="libx264")