LoginSignup
83
86

More than 5 years have passed since last update.

matplotlibで簡単にアニメーションをつくる(mp4, gif)

Last updated at Posted at 2017-04-13

matplotlib.animation: matplotlibベースの、お手軽アニメーション生成ライブラリ。

インストール

@mac
$ pip install matplotlib
$ brew install imagemagick # gif 保存用
$ brew install ffmpeg # mp4 保存用
matplotlib.rcの修正
$ python -c "import matplotlib;print(matplotlib.matplotlib_fname())"
/Users/riki/.pyenv/versions/ML-2.7.13/lib/python2.7/site-packages/matplotlib/mpl-data/matplotlibrc
$ atom /Users/riki/.pyenv/versions/ML-2.7.13/lib/python2.7/site-packages/matplotlib/mpl-data/matplotlibrc

# line 38
- backend : macosx
+ backend : Tkagg

Animationを生成する関数が2種類ある

  • ArtistAnimation: あらかじめ全てのフレームをlistで用意しておく
  • FuncAnimation: 各フレームを動的に生成する

個人的には ArtistAnimationの方がわかりやすいのでこちらをオススメする。
FuncAnimationの方が柔軟ではあるが、ArtistAnimationで不便は特に感じない。

ArtistAnimation

animation.ArtistAnimation(fig, artists, interval=200)
* fig: 大枠。matplotlibのfigureオブジェクト
* artists: 各フレームで描くartistオブジェクト(lineなど)のlistのlist
* interval: 各フレームの再生間隔 [ms]

artists引数をlistのlistにしないといけないところでerrorを出しやすいので注意。(詳細後述)


例1: sin波のアニメーション

anim_sin_wave.py
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()
x = np.arange(0, 10, 0.1)

ims = []
for a in range(50):
    y = np.sin(x - a)
    line, = plt.plot(x, y, "r")
    ims.append([line])

ani = animation.ArtistAnimation(fig, ims)
ani.save('anim.gif', writer="imagemagick")
ani.save('anim.mp4', writer="ffmpeg")
plt.show()

anim.gif

pyplot.plot関数は複数のグラフを一度にプロットできるので、返り値の型がlist。

lines = plt.plot(x1, y1, 'r', x2, y2, 'g', x3, y3, 'b')
print type(lines) # list
print len(lines) # 3
print type(lines[0]) # matplotlib.lines.Line2D

わかりやすさのため、メインコードでは敢えて unpackしてLine2Dオブジェクトを取り出して、そのあと、listに変更してからlistに追加する。

line, = plt.plot(x, y, "r")
ims.append([line])

animationの保存は、以下で行える(gifかmp4の好きな方でやればいい)

ani.save('anim.gif', writer="imagemagick")
ani.save('anim.mp4', writer="ffmpeg")

例2: 2次元画像のアニメーション

dynamic_image.py
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig = plt.figure()

def f(x, y):
    return np.sin(x) + np.cos(y)

x = np.linspace(0, 2 * np.pi, 120)
y = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
ims = []

for i in range(60):
    x += np.pi / 15.
    y += np.pi / 20.
    im = plt.imshow(f(x, y), animated=True)
    ims.append([im])

ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True,
                                repeat_delay=1000)

ani.save('anim.gif', writer="imagemagick")
ani.save('anim.mp4', writer="ffmpeg")
plt.show()

anim.gif

pyplot.imshow関数は、返り値の型がAxesImageオブジェクトなので、listにしてからlistに追加する。

im = plt.imshow([[]])
print type(im) # matplotlib.image.AxesImage
ims.append([im])
83
86
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
83
86