There's lots of options. (And you probably aren't finding the solutions easily because you aren't using the proper terms as your post title reflects. It seems you want to play a .gif
in Jupyter or an animated plot made of frames.)
First, addressing showing the gif inside Jupyter:
The easiest is to use JupyterLab to open a new notebook run your code after clicking here. (For using your code there, change that last line to anim.save('sine_wave.gif')
because I didn't bother installing imagemagick there, yet. Pillow is able to make the gif, and matplotlib will handle selecting Pillow for the task if you just don't specify writer
.)
When the gif file gets made, you can just double click on it in the file browser on the left side and it will play. You can arrange the window it plays in as you want relative the notebook by clicking on the tab above it and dragging and then releasing it as you want.
If you prefer the more traditional notebook for playing the gif in, you can simply put the following code in a cell after the gif file is generated:
from IPython.display import Image
Image("sine_wave.gif")
(Note that here it says for a local .gif
file you need to read the bytes and display it, like Image("sine_wave.gif","rb").read())
. And so that may be something to keep in mind if not as simple as I illustrate in the Unix system.)
Executing that notebook cell will play the gif as output for the cell if the gif image file is in the same folder with the notebook file.
Second, display alternatives instead of making a gif:
For how to properly get the plotting animation to play, not necessarily as a gif, I'd suggest adding controls following examples and links towards the bottom of the notebook that you can open in active form by clicking 'launch binder' here. You are looking for examples and links that use or involve FuncAnimation()
towards the bottom there. The ones I suggest involving frames allow you to control and play them using a widget or make HTML that can play and be controlled. Importantly, that widget approach will work even when the notebook is 'static' as you can see here. I put static in quotes because some active features will work in nbviewer, though usually note in Github preview, which trips up a lot of novices now that Github attempts a preview rendering for notebooks even of substantial length. (And if you need a portable HTML5-compatible video file to be generated, that is covered in that same section.) Here's a couple of variations on your code using related approaches to add the widget/frame generation that will work in active sessions here:
one option
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
from IPython.display import HTML, display
plt.style.use('seaborn-pastel')
def generate_animation():
fig = plt.figure()
ax = plt.axes(xlim=(0, 4), ylim=(-2, 2))
lineplot, = ax.plot([], [], lw=3)
def init():
lineplot.set_data([], [])
return lineplot, #return [lineplot] also works like in https://nbviewer.org/github/raphaelquast/jupyter_notebook_intro/blob/master/jupyter_nb_introduction.ipynb#pre-render-animations-and-export-to-HTML
def animate(i):
x = np.linspace(0, 4, 1000)
y = np.sin(2 * np.pi * (x - 0.01 * i))
lineplot.set_data([x], [y])
return [lineplot]
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=200, interval=20, blit=True)
display(HTML(anim.to_jshtml()))
plt.close(fig)
generate_animation()
another variant
# RUN THIS TWICE. SECOND TIME WILL BE NICE SINGLE PLOT DISPLAYED.
# January 2023 I was finding first time I ran this or code like at https://nbviewer.org/gist/fomightez/d862333d8eefb94a74a79022840680b1 that it output a non-interactive frame of plot, too. Just re-ran and then it is just the interactive one with widget.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
from IPython.display import HTML, display
plt.rcParams["animation.html"] = "jshtml"
plt.ioff() #needed so the second time you run it you get only single plot
plt.style.use('seaborn-pastel')
fig = plt.figure()
ax = plt.axes(xlim=(0, 4), ylim=(-2, 2))
lineplot, = ax.plot([], [], lw=3)
def init():
lineplot.set_data([], [])
return lineplot, #return [lineplot] also works like in https://nbviewer.org/github/raphaelquast/jupyter_notebook_intro/blob/master/jupyter_nb_introduction.ipynb#pre-render-animations-and-export-to-HTML
def animate(i):
x = np.linspace(0, 4, 1000)
y = np.sin(2 * np.pi * (x - 0.01 * i))
lineplot.set_data([x], [y])
return [lineplot]
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=200, interval=20, blit=True)
anim
A Jupyter notebook with those to options run and more fully explained is here; you'll note the widgets work there.
Click here to launch that notebook in an active, temporary Jupyter session served via MyBinder.org with the environment already having Python and everything needed to make the animation with a widget work in the notebook installed and working.