animation-in-a-notebook
animation in a notebook¶
Dans le notebook précédent, on a vu comment créer
- la grille rectangulaire puis hexagonale,
- les lames autour de ces points - puis un fonction pour les représenter.
On va maintenant utiliser:
http://matplotlib.org/api/animation_api.html
http://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/
... pour créer des animations de ces lames.
In [5]:
%%bash
cd /tmp
git clone https://github.com/jakevdp/JSAnimation.git
In [6]:
%%bash
cd /tmp/JSAnimation/
python setup.py install
In [7]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# JSAnimation import available at https://github.com/jakevdp/JSAnimation
from JSAnimation import IPython_display
In [8]:
%%writefile /tmp/EdgeGrid.py
import numpy as np
import matplotlib.pyplot as plt
class EdgeGrid():
def __init__(self):
self.figsize = 13
self.line_width = 4.
self.N_lame = 72
self.N_lame_X = np.int(np.sqrt(self.N_lame))#*np.sqrt(3) / 2)
self.lames = np.zeros((3, self.N_lame))
self.lames[0, :] = np.mod(np.arange(self.N_lame), self.N_lame_X)
self.lames[0, :] += np.mod(np.floor(np.arange(self.N_lame)/self.N_lame_X), 2)/2
self.lames[1, :] = np.floor(np.arange(self.N_lame)/self.N_lame_X)
self.lames[1, :] *= np.sqrt(3) / 2
self.lames[0, :] /= self.N_lame_X
self.lames[1, :] /= self.N_lame_X
self.lames_minmax = np.array([self.lames[0, :].min(), self.lames[0, :].max(), self.lames[1, :].min(), self.lames[1, :].max()])
self.lame_length = .45/self.N_lame_X
def show_edges(self, fig=None, a=None):
"""
Shows the quiver plot of a set of edges, optionally associated to an image.
"""
import pylab
import matplotlib.cm as cm
if fig==None:
fig = pylab.figure(figsize=(self.figsize, self.figsize))
if a==None:
border = 0.0
a = fig.add_axes((border, border, 1.-2*border, 1.-2*border), axisbg='w')
self.lines = self.set_lines()
a.add_collection(self.lines)
a.axis(c='b', lw=0)
pylab.setp(a, xticks=[])
pylab.setp(a, yticks=[])
marge = self.lame_length*3.
a.axis(self.lames_minmax + np.array([-marge, +marge, -marge, +marge]))
else:
self.update_lines()
pylab.draw()
return fig, a
def set_lines(self):
from matplotlib.collections import LineCollection
import matplotlib.patches as patches
# draw the segments
segments, colors, linewidths = list(), list(), list()
X, Y, Theta = self.lames[0, :], self.lames[1, :].real, self.lames[2, :]
for x, y, theta in zip(X, Y, Theta):
u_, v_ = np.cos(theta)*self.lame_length, np.sin(theta)*self.lame_length
segments.append([(x - u_, y - v_), (x + u_, y + v_)])
colors.append((0, 0, 0, 1))# black
linewidths.append(self.line_width)
return LineCollection(segments, linewidths=linewidths, colors=colors, linestyles='solid')
def update_lines(self):
from matplotlib.collections import LineCollection
import matplotlib.patches as patches
X, Y, Theta = self.lames[0, :], self.lames[1, :], self.lames[2, :]
segments = list()
for i, (x, y, theta) in enumerate(zip(X, Y, Theta)):
u_, v_ = np.cos(theta)*self.lame_length, np.sin(theta)*self.lame_length
segments.append([(x - u_, y - v_), (x + u_, y + v_)])
self.lines.set_segments(segments)
In [9]:
%run /tmp/EdgeGrid.py
In [10]:
# create a simple animation
fig, a = e.show_edges()
In [11]:
from matplotlib import animation
from JSAnimation import IPython_display
def init():
e.show_edges(fig, a)
def animate(i):
e.lames[2, :] = i*np.pi/100 + .0*np.pi*np.random.randn(e.N_lame)
e.update_lines()
N_frame = 100
animation.FuncAnimation(fig, animate, init_func=init, frames=N_frame, interval=1000./30, blit=True)
Out[11]:
In [12]:
def animate(i):
e.lames[2, :] = np.pi/3.*np.sin(2*i*np.pi/N_frame)
e.update_lines()
animation.FuncAnimation(fig, animate, init_func=init, frames=N_frame, interval=1000./30, blit=True)
Out[12]:
In [13]:
N_frame = 100
def animate(i):
e.lames[2, :] += .1 * 2 * np.pi * np.random.randn(e.lames[2, :].shape[0]) # brownian motion in orientation
e.lames[2, :] *= (1 - 1. * i / N_frame)* i / N_frame # damping at the end of the period
e.update_lines()
animation.FuncAnimation(fig, animate, init_func=init, frames=N_frame, interval=1000./30, blit=True)
Out[13]:
In [14]:
N_frame = 100
def animate(i):
e.lames[2, :] += e.lames[0, :] * .1 * 2 * np.pi * np.random.randn(e.lames[2, :].shape[0]) # brownian motion in orientation
e.lames[2, :] *= (1 - 1. * i / N_frame)* i / N_frame # damping at the end of the period
e.update_lines()
animation.FuncAnimation(fig, animate, init_func=init, frames=N_frame, interval=1000./30, blit=True)
Out[14]:
In [15]:
N_frame = 100
def animate(i):
e.lames[2, :] += ((e.lames[0, :]-.5)**2 +(e.lames[1, :]-.5)**2 ) * 1. * 2 * np.pi * np.random.randn(e.lames[2, :].shape[0]) # brownian motion in orientation
e.lames[2, :] *= (1 - 1. * i / N_frame)* i / N_frame # damping at the end of the period
e.update_lines()
animation.FuncAnimation(fig, animate, init_func=init, frames=N_frame, interval=1000./30, blit=True)
Out[15]:
In [16]:
N_frame = 100
def init():
e.lames[2, :] = np.arctan2((e.lames[0, :]-.5), (e.lames[1, :]-.5))
e.show_edges(fig, a)
def animate(i):
e.lames[2, :] += ((e.lames[0, :]-.5)**2 +(e.lames[1, :]-.5)**2 ) * 1. * 2 * np.pi * np.random.randn(e.lames[2, :].shape[0]) # brownian motion in orientation
e.lames[2, :] *= (1 - 1. * i / N_frame)* i / N_frame # damping at the end of the period
e.update_lines()
animation.FuncAnimation(fig, animate, init_func=init, frames=N_frame, interval=1000./30, blit=True)
Out[16]: