Встроенные анимации в Jupyter
У меня есть анимация python script (с использованием matplotlib funcAnimation), которая работает в Spyder, но не в Jupyter. Я пробовал следующие различные предложения, такие как добавление "% matplotlib inline" и изменение базы данных matplotlib на "Qt4agg", все без успеха. Я также попробовал запустить несколько анимаций (из Jupyter tutorials), ни одна из которых не сработала. Иногда я получаю сообщение об ошибке, и иногда появляется сюжет, но не оживляет. Кстати, я использовал pyplot.plot() для работы с использованием "% matplotlib inline".
Кто-нибудь знает о рабочем ноутбуке Jupyter с примером простой анимации SIMPLE, который использует funcAnimation. Заранее спасибо за помощь!
[Примечание: я нахожусь в Windows 7]
Ответы
Ответ 1
Бэкэнд для ноутбуков
'Inline' означает, что графики отображаются в виде png-графики. Эти png-изображения не могут быть анимированы. Хотя в принципе можно было бы создать анимацию, последовательно заменяя png-изображения, это, вероятно, нежелательно.
Решение состоит в том, чтобы использовать бэкэнд для ноутбука, который полностью совместим с FuncAnimation
, поскольку он отображает сам рисунок matplotlib:
%matplotlib notebook
jsanimation
Из matplotlib 2.1 on мы можем создать анимацию с использованием 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
, чтобы получить анимацию.
Также см. этот ответ для полного обзора.
Ответ 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
в фоновом режиме, но они не были правильно настроены на моем компьютере. Решение состояло в том, чтобы удалить их и восстановить их из источника с правильной конфигурацией. Подробнее см. вопрос, который я задал, с рабочим ответом Эндрю Хойссера: Анимация в записной книжке ipython (jupyter) - ValueError: операция ввода-вывода для закрытого файла
Итак, сначала попробуйте решение to_html5_video
, описанное выше, и если оно не работает, попробуйте также удалить/перестроить ffmpeg
и x264
.
Ответ 3
Вот ответ, который я собрал из нескольких источников, включая официальные примеры. Я тестировал последние версии Jupyter и Python.
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')
Ответ 4
Если у вас есть список изображений и вы хотите анимировать их, вы можете использовать что-то вроде этого:
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(imgs[0])
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=len(imgs), 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())