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
Cloning into 'JSAnimation'...
In [6]:
%%bash
cd /tmp/JSAnimation/
python setup.py install
running install
running build
running build_py
creating build
creating build/lib
creating build/lib/JSAnimation
copying JSAnimation/__init__.py -> build/lib/JSAnimation
copying JSAnimation/examples.py -> build/lib/JSAnimation
copying JSAnimation/html_writer.py -> build/lib/JSAnimation
copying JSAnimation/IPython_display.py -> build/lib/JSAnimation
creating build/lib/JSAnimation/icons
copying JSAnimation/icons/first.png -> build/lib/JSAnimation/icons
copying JSAnimation/icons/last.png -> build/lib/JSAnimation/icons
copying JSAnimation/icons/next.png -> build/lib/JSAnimation/icons
copying JSAnimation/icons/pause.png -> build/lib/JSAnimation/icons
copying JSAnimation/icons/play.png -> build/lib/JSAnimation/icons
copying JSAnimation/icons/prev.png -> build/lib/JSAnimation/icons
copying JSAnimation/icons/reverse.png -> build/lib/JSAnimation/icons
running install_lib
creating /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation
copying build/lib/JSAnimation/__init__.py -> /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation
copying build/lib/JSAnimation/examples.py -> /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation
copying build/lib/JSAnimation/html_writer.py -> /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation
creating /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation/icons
copying build/lib/JSAnimation/icons/first.png -> /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation/icons
copying build/lib/JSAnimation/icons/last.png -> /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation/icons
copying build/lib/JSAnimation/icons/next.png -> /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation/icons
copying build/lib/JSAnimation/icons/pause.png -> /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation/icons
copying build/lib/JSAnimation/icons/play.png -> /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation/icons
copying build/lib/JSAnimation/icons/prev.png -> /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation/icons
copying build/lib/JSAnimation/icons/reverse.png -> /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation/icons
copying build/lib/JSAnimation/IPython_display.py -> /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation
byte-compiling /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation/__init__.py to __init__.cpython-34.pyc
byte-compiling /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation/examples.py to examples.cpython-34.pyc
byte-compiling /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation/html_writer.py to html_writer.cpython-34.pyc
byte-compiling /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation/IPython_display.py to IPython_display.cpython-34.pyc
running install_egg_info
Writing /Users/lolo/.pyenv/versions/3.4.3/lib/python3.4/site-packages/JSAnimation-0.1-py3.4.egg-info
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)
  
Overwriting /tmp/EdgeGrid.py
In [9]:
%run /tmp/EdgeGrid.py
In [10]:
# create a simple animation
fig, a = e.show_edges()
No description has been provided for this image
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]:
No description has been provided for this image

Once Loop Reflect
<matplotlib.figure.Figure at 0x11387f518>
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]:
No description has been provided for this image

Once Loop Reflect
<matplotlib.figure.Figure at 0x113886390>
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]:
No description has been provided for this image

Once Loop Reflect
<matplotlib.figure.Figure at 0x1120c52b0>
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]:
No description has been provided for this image

Once Loop Reflect
<matplotlib.figure.Figure at 0x1120c51d0>
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]:
No description has been provided for this image

Once Loop Reflect
<matplotlib.figure.Figure at 0x1138b5ba8>
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]:
No description has been provided for this image

Once Loop Reflect
<matplotlib.figure.Figure at 0x1138bc908>