{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Dans un notebook précédent, on a vu comment créer une grille hexagonale et comment l'animer.\n", "\n", "On va maintenant utiliser MoviePy pour animer ces plots.\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%load_ext autoreload\n", "%autoreload 2" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [], "source": [ "from elasticite import EdgeGrid\n", "e = EdgeGrid()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Cette librairie permet de faire des animations depuis diverses librairies de visualisation, comme:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import os\n", "name = 'sinc_vispy'\n", "fps = 25\n", "if not os.path.isfile(os.path.join('../files/2015-10-14_elasticite/', name + '.mp4')):\n", " from moviepy.editor import VideoClip\n", " import numpy as np\n", " from vispy import app, scene\n", " app.use_app('pyglet')\n", " from vispy.gloo.util import _screenshot\n", "\n", " canvas = scene.SceneCanvas(keys='interactive')\n", " view = canvas.central_widget.add_view()\n", " xx, yy = np.arange(-1,1,.02),np.arange(-1,1,.02)\n", " X,Y = np.meshgrid(xx,yy)\n", " R = np.sqrt(X**2+Y**2)\n", " Z = lambda t : 0.1*np.sin(10*R-2*np.pi*t)\n", " surface = scene.visuals.SurfacePlot(x= xx-0.1, y=yy+0.2, z= Z(0),\n", " shading='smooth', color=(0.5, 0.5, 1, 1))\n", " view.add(surface)\n", "\n", " # Use a 3D camera\n", " # Manual bounds; Mesh visual does not provide bounds yet\n", " # Note how you can set bounds before assigning the camera to the viewbox\n", " cam = scene.TurntableCamera(elevation=30, azimuth=30, up='z', distance=2)\n", " view.camera = cam\n", "\n", " canvas.show()\n", "\n", " # ANIMATE WITH MOVIEPY\n", " def make_frame(t):\n", " surface.set_data(z = Z(t)) # Update the mathematical surface\n", " canvas.on_draw(None) # Update the image on Vispy's canvas\n", " return _screenshot((0,0,canvas.size[0],canvas.size[1]))[:,:,:3]\n", "\n", " animation = VideoClip(make_frame, duration=1).resize(width=350)\n", " animation.write_videofile('../files/2015-10-14_elasticite/' + name + '.mp4', fps=fps)\n", "e.ipython_display(name)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Mais ce qui nous intéresse c'est de convertir nos trames construites avec matplotlib:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "name = 'sinc_mpl' \n", "if not os.path.isfile(os.path.join('../files/2015-10-14_elasticite/', name + '.mp4')):\n", " import matplotlib.pyplot as plt\n", " import numpy as np\n", " from moviepy.video.io.bindings import mplfig_to_npimage\n", " import moviepy.editor as mpy\n", "\n", " # DRAW A FIGURE WITH MATPLOTLIB\n", " duration = 2.\n", "\n", " fig_mpl, ax = plt.subplots(1,figsize=(5,3), facecolor='white')\n", " xx = np.linspace(-2,2,200) # the x vector\n", " zz = lambda d: np.sinc(xx**2)+np.sin(xx+d) # the (changing) z vector\n", " ax.set_title(\"Elevation in y=0\")\n", " ax.set_ylim(-1.5,2.5)\n", " line, = ax.plot(xx, zz(0), lw=3)\n", "\n", " # ANIMATE WITH MOVIEPY (UPDATE THE CURVE FOR EACH t). MAKE A GIF.\n", "\n", " def make_frame_mpl(t):\n", " line.set_ydata( zz(2*np.pi*t/duration)) # <= Update the curve\n", " return mplfig_to_npimage(fig_mpl) # RGB image of the figure\n", "\n", " animation = mpy.VideoClip(make_frame_mpl, duration=duration)\n", " animation.write_videofile('../files/2015-10-14_elasticite/' + name + '.mp4', fps=fps)\n", "e.ipython_display(name)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "scrolled": false }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "name = 'circle'\n", "if not os.path.isfile(os.path.join('../files/2015-10-14_elasticite/', name + '.mp4')):\n", " import matplotlib as mpl\n", " import matplotlib.pyplot as plt\n", " import numpy as np\n", " from moviepy.video.io.bindings import mplfig_to_npimage\n", " import moviepy.editor as mpy\n", " duration = 3.\n", " fig_mpl, ax = plt.subplots(1, figsize=(6, 5), facecolor='white')\n", "\n", " def draw_elementary_pattern(ax, center):\n", " ax.add_artist(mpl.patches.Wedge(center, 1., 0, 180, width=.1))\n", "\n", " def make_frame_mpl(t):\n", " ax.cla()\n", " draw_elementary_pattern(ax, t/duration)\n", " return mplfig_to_npimage(fig_mpl) # RGB image of the figure\n", "\n", " animation = mpy.VideoClip(make_frame_mpl, duration=duration)\n", " animation.write_videofile('../files/2015-10-14_elasticite/' + name + '.mp4', fps=fps)\n", "e.ipython_display(name)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pour le plaisir, une autre animation" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "name = 'svm'\n", "if not os.path.isfile(os.path.join('../files/2015-10-14_elasticite/', name + '.mp4')):\n", " import numpy as np\n", " import matplotlib.pyplot as plt\n", " from sklearn import svm # sklearn = scikit-learn\n", " from sklearn.datasets import make_moons\n", " from moviepy.editor import VideoClip\n", " from moviepy.video.io.bindings import mplfig_to_npimage\n", "\n", " X, Y = make_moons(50, noise=0.1, random_state=2) # semi-random data\n", "\n", " fig, ax = plt.subplots(1, figsize=(4, 4), facecolor=(1,1,1))\n", " fig.subplots_adjust(left=0, right=1, bottom=0)\n", " xx, yy = np.meshgrid(np.linspace(-2,3,500), np.linspace(-1,2,500))\n", "\n", " def make_frame(t):\n", " ax.clear()\n", " ax.axis('off')\n", " ax.set_title(\"SVC classification\", fontsize=16)\n", "\n", " classifier = svm.SVC(gamma=2, C=1)\n", " # the varying weights make the points appear one after the other\n", " weights = np.minimum(1, np.maximum(0, t**2+10-np.arange(50)))\n", " classifier.fit(X, Y, sample_weight=weights)\n", " Z = classifier.decision_function(np.c_[xx.ravel(), yy.ravel()])\n", " Z = Z.reshape(xx.shape)\n", " ax.contourf(xx, yy, Z, cmap=plt.cm.bone, alpha=0.8,\n", " vmin=-2.5, vmax=2.5, levels=np.linspace(-2,2,20))\n", " ax.scatter(X[:,0], X[:,1], c=Y, s=50*weights, cmap=plt.cm.bone)\n", "\n", " return mplfig_to_npimage(fig)\n", "\n", " animation = VideoClip(make_frame, duration = 7)\n", " animation.write_videofile('../files/2015-10-14_elasticite/' + name + '.mp4', fps=fps)\n", "e.ipython_display(name)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pour notre cas, on veut animer nos grilles et on simplifie la syntaxte redondante:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "name = 'test_grid'\n", "import numpy as np\n", "\n", "e = EdgeGrid(verb=False, structure=False)\n", "def make_lames(e):\n", " return e.t*np.pi/duration\n", "\n", "duration = 3.\n", "e.make_anim(name, make_lames, duration=duration)\n", "e.ipython_display(name)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "
\n", "
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "name = 'test_grid2'\n", "import numpy as np\n", "\n", "e = EdgeGrid(verb=False, structure=False)\n", "\n", "def make_lames(e):\n", " return e.lames[0, :] * np.pi + e.t*np.pi/duration\n", "\n", "duration = 3.\n", "e.make_anim(name, make_lames, duration=duration)\n", "e.ipython_display(name)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.1" } }, "nbformat": 4, "nbformat_minor": 0 }