Jupyter 中的内联动画
Posted
技术标签:
【中文标题】Jupyter 中的内联动画【英文标题】:Inline animations in Jupyter 【发布时间】:2017-09-12 16:40:33 【问题描述】:我有一个 python 动画脚本(使用 matplotlib 的 funcAnimation),它在 Spyder 中运行,但不在 Jupyter 中。我尝试了各种建议,例如添加“%matplotlib inline”并将 matplotlib 后端更改为“Qt4agg”,但均未成功。我还尝试过运行几个示例动画(来自 Jupyter 教程),但都没有奏效。有时我会收到一条错误消息,有时情节会出现,但没有动画。顺便说一句,我已经让 pyplot.plot() 使用“%matplotlib inline”工作。
有谁知道有一个使用 funcAnimation 的简单内联动画示例的工作 Jupyter 笔记本。提前感谢您的帮助!
[注意:我使用的是 Windows 7]
【问题讨论】:
【参考方案1】:笔记本后端
'Inline' 表示绘图显示为 png 图形。那些 png 图片不能动画化。虽然原则上可以通过连续替换 png 图像来构建动画,但这可能是不希望的。
一种解决方案是使用笔记本后端,它与FuncAnimation
完全兼容,因为它可以渲染 matplotlib 图形本身:
%matplotlib notebook
js动画
从 matplotlib 2.1 开始,我们可以使用 javascript 创建动画。这类似于ani.to_html5()
解决方案,只是它不需要任何视频编解码器。
from IPython.display import HTML
HTML(ani.to_jshtml())
一些完整的例子:
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()
ax.axis([0,2*np.pi,-1,1])
l, = ax.plot([],[])
def animate(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())
或者,将 jsanimation 设置为显示动画的默认设置,
plt.rcParams["animation.html"] = "jshtml"
然后在最后简单地声明ani
来获取动画。
另请参阅this answer 了解完整概述。
【讨论】:
AttributeError: 'FuncAnimation' 对象没有属性 'to_jshtml' 在 matplotlib 2.1.0 版本中添加了 to_jshtml:matplotlib.org/users/prev_whats_new/whats_new_2.1.0.html!pip install matplotlib --upgrade
当我将示例复制到网络中时,它在我第一次执行时运行良好。第二次返回动画和一个我似乎无法摆脱的空图。它来自哪里?
@AliceSchwarze 将plt.close()
放在ani = ...
声明之后以摆脱初始情节。然后第二个ani
启动动画。【参考方案2】:
本教程中有一个简单的示例:http://louistiao.me/posts/notebooks/embedding-matplotlib-animations-in-jupyter-notebooks/
总结上面的教程,你基本上需要这样的东西:
from matplotlib import animation
from IPython.display import HTML
# <insert animation setup code here>
anim = animation.FuncAnimation() # With arguments of course!
HTML(anim.to_html5_video())
但是...
我很难让它发挥作用。本质上,问题在于上述使用(默认情况下)ffmpeg
和x264
在后台编解码器,但这些在我的机器上没有正确配置。解决方案是卸载它们并使用正确的配置从源代码重建它们。有关更多详细信息,请参阅我提出的问题以及 Andrew Heusser 的有效答案:Animations in ipython (jupyter) notebook - ValueError: I/O operation on closed file
所以,先试试上面的to_html5_video
解决方案,如果不行再试试ffmpeg
和x264
的卸载/重建。
【讨论】:
【参考方案3】:另一种选择:
import matplotlib.animation
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams["animation.html"] = "jshtml"
plt.rcParams['figure.dpi'] = 150
plt.ioff()
fig, ax = plt.subplots()
x= np.linspace(0,10,100)
def animate(t):
plt.cla()
plt.plot(x-t,x)
plt.xlim(0,10)
matplotlib.animation.FuncAnimation(fig, animate, frames=10)
【讨论】:
【参考方案4】:这是我从多个来源(包括官方示例)汇总的答案。我使用最新版本的 Jupyter 和 Python 进行了测试。
下载FFmpeg (http://ffmpeg.zeranoe.com/builds/) 安装 FFmpeg 确保更新环境变量 ( http://www.wikihow.com/Install-FFmpeg-on-Windows )。 在下面的 Jupyter 中运行此脚本。变量imageList
是唯一需要修改的东西。它是图像列表(您的输入)。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from IPython.display import HTML
#=========================================
# Create Fake Images using Numpy
# You don't need this in your code as you have your own imageList.
# This is used as an example.
imageList = []
x = np.linspace(0, 2 * np.pi, 120)
y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
for i in range(60):
x += np.pi / 15.
y += np.pi / 20.
imageList.append(np.sin(x) + np.cos(y))
#=========================================
# Animate Fake Images (in Jupyter)
def getImageFromList(x):
return imageList[x]
fig = plt.figure(figsize=(10, 10))
ims = []
for i in range(len(imageList)):
im = plt.imshow(getImageFromList(i), animated=True)
ims.append([im])
ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True, repeat_delay=1000)
plt.close()
# Show the animation
HTML(ani.to_html5_video())
#=========================================
# Save animation as video (if required)
# ani.save('dynamic_images.mp4')
【讨论】:
【参考方案5】:如果您有一个图像列表并希望通过它们制作动画,您可以使用以下内容:
from keras.preprocessing.image import load_img, img_to_array
from matplotlib import animation
from IPython.display import HTML
import glob
%matplotlib inline
def plot_images(img_list):
def init():
img.set_data(img_list[0])
return (img,)
def animate(i):
img.set_data(img_list[i])
return (img,)
fig = figure()
ax = fig.gca()
img = ax.imshow(img_list[0])
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=len(img_list), interval=20, blit=True)
return anim
imgs = [img_to_array(load_img(i)) for i in glob.glob('*.jpg')]
HTML(plot_images(imgs).to_html5_video())
【讨论】:
为了让它工作,你必须下载 ffmpeg 到你的操作系统,然后plt.rcParams['animation.ffmpeg_path'] = '/usr/bin/ffmpeg'
。将/usr/bin/ffmpeg'
替换为您操作系统中ffmpeg 二进制文件的路径。以上是关于Jupyter 中的内联动画的主要内容,如果未能解决你的问题,请参考以下文章
是否可以使用 pyqtgraph 函数在 Jupyter Notebook 上内联绘图?
在 Jupyter 中使用 plotly 在离线模式下创建动画图表
尝试使用 matplotlib 内联绘图时,为啥在 jupyter notebook 中出现 NonGuiException?