Skip to content

Commit

Permalink
update documentation & README
Browse files Browse the repository at this point in the history
  • Loading branch information
jakevdp committed May 19, 2013
1 parent 1ace65b commit 02777eb
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 76 deletions.
3 changes: 3 additions & 0 deletions JSAnimation/html_writer.py
Expand Up @@ -193,6 +193,9 @@ def _load_base64(self, filename):
var loop_select_id = "_anim_loop_select{id}";
var frames = new Array({Nframes});
{fill_frames}
/* set a timeout to make sure all the above elements are created before
the object is initialized. */
setTimeout(function() {{
anim{id} = new Animation(frames, img_id, slider_id, loop_select_id);
}}, 0);
Expand Down
48 changes: 32 additions & 16 deletions README.md
@@ -1,28 +1,44 @@
JSAnimation
===========

Experimenting with frame-based Javascript animations.
Eventually, I'd like this to become a plugin for the IPython notebook, so
that animations can be embedded automatically. For a couple examples of
initial ideas along these lines, see
[this notebook](http://nbviewer.ipython.org/5573741) and
[this blog post](http://jakevdp.github.io/blog/2013/05/12/embedding-matplotlib-animations/).
*Copyright (c) 2013, Jake Vanderplas*

*License: [BSD](http://opensource.org/licenses/BSD-2-Clause)*

Trying it Out
-------------
To test this with a basic animation using non-embedded frames, run
This package implements an HTML/Javascript writer for Matplotlib animations.
The result can be embedded in a web page, or an IPython notebook.

Testing it Out
--------------
There are several scripts which demonstrate this. ``make_animation.py``
creates a basic animation, with the frame data embedded within the HTML
document. Run this using

python make_animation.py

and then use your web browser to open the file ``animation.html``.
This script creates the ``animation_frames`` directory, which contains the
individual png image representing each frame.
and then open the resulting file, ``animation.html`` using your web browser.
This file is created using the option ``embed = True``, which means that the
image data is embedded directly in the html file in base64-representation.
This means that the animation is entirely self-contained in the file.

To test a more sophisticated animation with embedded frames, run
A more sophisticated animation can be created using

python make_lorenz_animation.py

and then use your web browser to open the file ``lorenz_animation.html``.
This does not create a frame directory, but rather embeds the frames directly
in the html document in base64 encoding.
(adapted from [this blog post](http://jakevdp.github.io/blog/2013/02/16/animating-the-lorentz-system-in-3d/)
The resulting file, ``lorenz_animation.py``, can be opened in your web browser.
This animation is created using the option ``embed = False``, which means that
the frames are individually stored in the directory ``lorenz_animation_frames``.
This prevents the html file from being too large.

If you have IPython notebook installed, you can open ``animation_example.ipynb``
to see the automatic animation representation within the notebook. Simply
import the ``IPython_display`` submodule, create the animation, and the
javascript widget will appear embedded in your notebook window.

Browser Compatibility
---------------------
Because the animation widget uses an HTML5 slider element, it does not work
in some browsers. In particular, Firefox does not yet support this element.
For a comprehensive list of supported browsers, see
[this list](http://caniuse.com/input-range).
83 changes: 29 additions & 54 deletions animation_example.ipynb
Expand Up @@ -8,22 +8,30 @@
{
"cells": [
{
"cell_type": "code",
"collapsed": false,
"input": [
"%pylab inline"
],
"language": "python",
"cell_type": "heading",
"level": 1,
"metadata": {},
"outputs": []
"source": [
"IPython Javascript Animation Plugin"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is an example of embedding an animation via javascript into an IPython notebook.\n",
"It requires the ``JSAnimation`` import, available at http://github.com/jakevdp/JSAnimation\n",
"\n",
"The animation makes use of the HTML5 slider element, which is not yet supported by\n",
"Firefox. For a comprehensive list of browser support for this element, see\n",
"http://caniuse.com/input-range"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# This import available at https://github.com/jakevdp/JSAnimation\n",
"from JSAnimation import IPython_display\n",
"from matplotlib import animation"
"%pylab inline"
],
"language": "python",
"metadata": {},
Expand All @@ -33,60 +41,27 @@
"cell_type": "code",
"collapsed": false,
"input": [
"# create a basic animation\n",
"fig = plt.figure(figsize=(4, 3))\n",
"# JSAnimation import available at https://github.com/jakevdp/JSAnimation\n",
"from JSAnimation import IPython_display\n",
"from matplotlib import animation\n",
"\n",
"# create a simple animation\n",
"fig = plt.figure()\n",
"ax = plt.axes(xlim=(0, 10), ylim=(-2, 2))\n",
"line, = ax.plot([], [], lw=2)\n",
"\n",
"x = np.linspace(0, 10, 1000)\n",
"\n",
"def init():\n",
" line.set_data([], [])\n",
" return line,\n",
"\n",
"def animate(i):\n",
" x = np.linspace(0, 10, 1000)\n",
" y = np.cos(i * 0.02 * np.pi) * np.sin(x - i * 0.02 * np.pi)\n",
" line.set_data(x, y)\n",
" line.set_data(x, np.cos(i * 0.02 * np.pi) * np.sin(x - i * 0.02 * np.pi))\n",
" return line,\n",
"\n",
"anim = animation.FuncAnimation(fig, animate, init_func=init,\n",
" frames=100, interval=20, blit=True)\n",
"\n",
"# close figure so that an empty frame is not displayed\n",
"plt.close(fig)"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# This should lead to a nice HTML representation\n",
"# via the _repr_html_ method. It spins for a while,\n",
"# which means the result is being computed. But it\n",
"# shows nothing!\n",
"anim"
],
"language": "python",
"metadata": {},
"outputs": []
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# If we embed the result in an iframe, it works.\n",
"# So why doesn't it work as raw HTML?\n",
"from IPython.display import HTML\n",
"\n",
"html = anim._repr_html_()\n",
"\n",
"import tempfile\n",
"with tempfile.NamedTemporaryFile() as f:\n",
" open(f.name, 'w').write(html)\n",
" data = open(f.name, 'rb').read().encode('base64')\n",
"HTML('<iframe src=\"data:text/html;base64,{0}\" width=\"600\" height=\"400\"></iframe>'.format(data))"
"animation.FuncAnimation(fig, animate, init_func=init,\n",
" frames=100, interval=20, blit=True)"
],
"language": "python",
"metadata": {},
Expand Down
7 changes: 2 additions & 5 deletions make_animation.py
Expand Up @@ -21,8 +21,5 @@ def animate(i):
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=100, interval=20, blit=True)

# set embed_frames=False to save each frame as an individual image file
anim.save('animation.html', writer=HTMLWriter(embed_frames=False))

# set embed_frames=True to embed each frame in the html using base64 encoding
#anim.save('animation.html', writer=HTMLWriter(embed_frames=True))
# set embed_frames=True to embed base64-encoded frames directly in the HTML
anim.save('animation.html', writer=HTMLWriter(embed_frames=True))
9 changes: 8 additions & 1 deletion make_lorenz_animation.py
@@ -1,3 +1,9 @@
"""
Lorenz animation
Adapted from http://jakevdp.github.io/blog/2013/02/16/animating-the-lorentz-system-in-3d/
"""

import numpy as np
from scipy import integrate

Expand Down Expand Up @@ -78,6 +84,7 @@ def animate(i):
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=200, interval=30, blit=True)

anim.save('lorenz_animation.html', writer=HTMLWriter(embed_frames=True))
# set embed_frames=False so that frames will be stored individually
anim.save('lorenz_animation.html', writer=HTMLWriter(embed_frames=False))


0 comments on commit 02777eb

Please sign in to comment.