Animation in iPython notebook
Asked Answered
F

4

34

I am trying to put animations in an iPython notebook and am not finding a solution. I saw one post that discussed using interactive widgets, but there are a couple problems that I have with this: First, every example I see with widgets uses a slider or some other input, whereas I just want the animation to run automatically when the cell is run. Second, all the documentation seems out of date on Jupyter's site--whenever I download and run their notebooks I get these messages about certain modules being deprecated and then later in the file something fails to run, presumably because they're trying to import and access files that no longer exist.

I've seen a few other pages on the topic but they often require downloading binaries or other modules, but I'm partly using this to teach some students Math and I've gotten them to download Anaconda--I was hoping to not further confuse the issue by making them also download and install more complicated things all while spending time not talking about the Math.

So in short, is there a way that I can create animations in an iPython notebook that only require the use of simple import commands that will run out-of-the-box so to speak with the software that comes from Anaconda?

[Edit: I should also note that I've used Tkinter to make animations, and I could make one in matplotlib I'm sure. So if there were a way to get the animations you produce with those to render in an iPython notebook, that would certainly be a working solution for me.]

[Further edit: I suppose I could also say what I am hoping to animate at the moment, although I really want to be pretty flexible about the range of things I could animate if I decide to. Right now I'm trying to make a digital clock that displays each digit in Sumerian base-60 numerals to illustrate a different counting and base system. So it should initially display | then after a second || and so on until ten gets represented as < and so on until eventually the clock ticks over to a minute where it now displays |:| to represent one minute, one second.]

[Note to future humans: If you're implementing some animation and are willing to publicly host it, please leave a link to it in the comments! I'm curious to see how people are making animations these days, and also a little curious to see what they're animating.]

Fade answered 21/2, 2016 at 4:58 Comment(2)
There is JSAnimation, but it requires extra installation. You can replace an output such as a plot with IPython.display.clear_output, but it won't be smooth enough to properly animate something.Seraglio
JSAnimation does not require extra installation anymore. It has been merged into matplotlib since version 2.1. Usage is shown in the last snippet in answer by @ImportanceOfBeingErnest.Sift
C
56

Some options you have for animating plots in Jupyter/IPython, using matplotlib:

  • Using display in a loop Use IPython.display.display(fig) to display a figure in the output. Using a loop you would want to clear the output before a new figure is shown. Note that this technique gives in general not so smooth resluts. I would hence advice to use any of the below.

    import matplotlib.pyplot as plt
    import matplotlib.animation
    import numpy as np
    from IPython.display import display, clear_output
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    l, = ax.plot([0,2*np.pi],[-1,1])
    
    animate = lambda i: l.set_data(t[:i], x[:i])
    
    for i in range(len(x)):
        animate(i)
        clear_output(wait=True)
        display(fig)
        
    plt.show()
  • %matplotlib notebook Use IPython magic %matplotlib notebook to set the backend to the notebook backend. This will keep the figure alive instead of displaying a static png file and can hence also show animations.
    Complete example:

    %matplotlib notebook
    import matplotlib.pyplot as plt
    import matplotlib.animation
    import numpy as np
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    l, = ax.plot([0,2*np.pi],[-1,1])
    
    animate = lambda i: l.set_data(t[:i], x[:i])
    
    ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
    
    plt.show()
  • %matplotlib tk Use IPython magic %matplotlib tk to set the backend to the tk backend. This will open the figure in a new plotting window, which is interactive and can thus also show animations.
    Complete example:

    %matplotlib tk
    import matplotlib.pyplot as plt
    import matplotlib.animation
    import numpy as np
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    l, = ax.plot([0,2*np.pi],[-1,1])
    
    animate = lambda i: l.set_data(t[:i], x[:i])
    
    ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
    
    plt.show()
  • Convert animation to mp4 video (option mentionned by @Perfi already):

    from IPython.display import HTML
    HTML(ani.to_html5_video())
    

    or use plt.rcParams["animation.html"] = "html5" at the beginning of the notebook. This will require to have ffmpeg video codecs available to convert to HTML5 video. The video is then shown inline. This is therefore compatible with %matplotlib inline backend. Complete example:

    %matplotlib inline
    import matplotlib.pyplot as plt
    plt.rcParams["animation.html"] = "html5"
    import matplotlib.animation
    import numpy as np
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    l, = ax.plot([0,2*np.pi],[-1,1])
    
    animate = lambda i: l.set_data(t[:i], x[:i])
    
    ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
    ani
    %matplotlib inline
    import matplotlib.pyplot as plt
    import matplotlib.animation
    import numpy as np
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    l, = ax.plot([0,2*np.pi],[-1,1])
    
    animate = lambda i: l.set_data(t[:i], x[:i])
    
    ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
    
    from IPython.display import HTML
    HTML(ani.to_html5_video())
  • Convert animation to JavaScript:

    from IPython.display import HTML
    HTML(ani.to_jshtml())
    

    or use plt.rcParams["animation.html"] = "jshtml" at the beginning of the notebook. This will display the animation as HTML with JavaScript. This highly compatible with most new browsers and also with the %matplotlib inline backend. It is available in matplotlib 2.1 or higher.
    Complete example:

    %matplotlib inline
    import matplotlib.pyplot as plt
    plt.rcParams["animation.html"] = "jshtml"
    import matplotlib.animation
    import numpy as np
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    l, = ax.plot([0,2*np.pi],[-1,1])
    
    animate = lambda i: l.set_data(t[:i], x[:i])
    
    ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
    ani
    %matplotlib inline
    import matplotlib.pyplot as plt
    import matplotlib.animation
    import numpy as np
    
    t = np.linspace(0,2*np.pi)
    x = np.sin(t)
    
    fig, ax = plt.subplots()
    l, = ax.plot([0,2*np.pi],[-1,1])
    
    animate = lambda i: l.set_data(t[:i], x[:i])
    
    ani = matplotlib.animation.FuncAnimation(fig, animate, frames=len(t))
    
    from IPython.display import HTML
    HTML(ani.to_jshtml())
Counteract answered 22/10, 2017 at 19:55 Comment(6)
Quick question, since I don't understand these backend things at all, how would you recommend learning about them? Is there a book, or some general topic that I can look up, in order to study whatever is necessary to understand them? Or perhaps a better question: In what class would you learn about these, if you were taking a CompSci course?Fade
I have no idea about CompSci courses. I guess you learn about them by using them. There is a matplotlib page about them. Concerning Jupyter, there is this page as introduction.Counteract
Converting animation to JavaScript in matplotlib is a boon, especially as it removes the hassle of installing ffmpeg codecs for someone in a hurry. @Counteract Nice use of code snippets in the answer. Can I know if putting the code as CSS in the answer was a deliberate choice or is it the same for HTML/JS etc? I must confess I spent a few confused minutes just clicking the Run code snippet expecting to see some python output.Sift
@Sift Sorry for the confusion. I misused this css/javascrip feature to hide the code in order not to clutter the answer. This allows to clearly see all options in the answer, but at the same time gives a complete example for anyone in need of it (I always like to provide mcves to make some command unambiguous.) Unfortunately this "Hide Code" feature is not available for other languages like python.Counteract
The first (slow) method above is very useful for on-line animations, i.e., for when you are generating data frame by frame, rather than having it all a priori.Damalus
For future readers: none of these solutions work as expected. Some of them display blank "windows", others show two "windows".Vaishnava
B
11

You may find this tutorial interesting.

If you can turn what you need into a matplotlib animation, and I'm fairly sure from your description that it's possible, you can then use

from matplotlib import rc, animation
rc('animation', html='html5')

and display your animation using

anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=N, interval=20, blit=True)
anim

Might come in handy!

Butane answered 9/6, 2016 at 16:13 Comment(1)
why does this snippet display two "windows", one blank and another one with the video?Vaishnava
T
3

Jupyter widgets is a good way of displaying animations. The code below displays an animated gif.....

from ipywidgets import Image
from IPython import display
animatedGif = "animatedGifs/01-progress.gif" #path relative to your notebook
file = open(animatedGif , "rb")
image = file.read()
progress= Image(
    value=image,
    format='gif',
    width=100,
    height=100)
display.display(progress)

You can close this animation using:

progress.close()

N.B. I found a few nice animated gifs from http://www.downgraf.com/inspiration/25-beautiful-loading-bar-design-examples-gif-animated/.

Twocycle answered 13/6, 2017 at 12:14 Comment(0)
T
2

I had a similar problem, and this question helped me get started. I put together a notebook that illustrates using FuncAnimation along with good explanations of why the notebook does some things the way it does. It also has links to instructions on FFmpeg. It also has links to the examples I used in developing and understanding of animations. You can view my contribution at: Animation Illustration

For your question, you might find interactive sliders a better tool. I also created a notebook which demonstrates interactive widgets in Jupyter. It is available here; however, the interactive parts don't work there.

Both are available in a GitHub Repostory

Tweezers answered 1/11, 2016 at 15:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.