簡単に考えていたが、難解でした。
ということで、Gifアニメーションに出力できました。
###やったこと
・animation.ArtistAnimation(fig, ims, interval=100)もanimation.FuncAnimation(fig, plot, interval=100)
・mp4やaviで動画出力
・PILを使ってGifアニメーションとして出力させる
###・animation.ArtistAnimation(fig, ims, interval=100)もanimation.FuncAnimation(fig, plot, interval=100)
はっきり言って使いたくない。
コードは簡単で、以下のとおり
性能を見たいので、4分割のグラフに表示している。
※もちろん、一か所であればそれなりに使える
【参考】
①matplotlib でアニメーションを作る
②matplotlibで簡単にアニメーションをつくる(mp4, gif)
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
# プロット領域(Figure, Axes)の初期化
fig = plt.figure()
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(223)
ax4 = fig.add_subplot(224)
ax1.axis([-1.2, 1.2, -1.2, 1.2])
ax2.axis([0, 100, -2, 2])
# 棒グラフの作成
s = 1
ims = []
for i in range(10):
rand = np.random.randn(100) # 100個の乱数を生成
im = ax1.plot(rand) # 乱数をグラフにする
ims.append(im) # グラフを配列 ims に追加
im = ax2.plot(rand) # 乱数をグラフにする
ims.append(im)
im = ax3.plot(rand) # 乱数をグラフにする
ims.append(im)
im = ax4.plot(rand) # 乱数をグラフにする
ims.append(im)
ani = animation.ArtistAnimation(fig, ims, interval=100)
ani.save('anim.gif', writer="imagemagick")
#ani.save('anim.mp4', writer="ffmpeg")
plt.show()
そして、コードの最後に記載しているが、imagemagick、ffmpeg、どちらもうまく動かなかった。
一時的なものかも知れないが、imagemagickはリンクにとべずインストールできなかった。⇒なんと本日はダウンロードできた⇒そして無事にanim.gifが保存できました
※ffmpegは動きませんでした。
ダウンロードページ@imagemagick
###・mp4やaviで動画出力
これはこれまでも利用したOpenCVで出力する方法。ただし、Gifアニメーションには対応していない。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import cv2
from PIL import Image, ImageDraw
def cv_fourcc(c1, c2, c3, c4):
return (ord(c1) & 255) + ((ord(c2) & 255) << 8) + \
((ord(c3) & 255) << 16) + ((ord(c4) & 255) << 24)
OUT_FILE_NAME = "output_video.mp4"
#OUT_FILE_NAME = "output_video.avi"
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
dst = cv2.imread('image.png') #一度、savefigしてから再読み込み
rows,cols,channels = dst.shape
out = cv2.VideoWriter(OUT_FILE_NAME, int(fourcc), int(10), (int(cols), int(rows)))
#out = cv2.VideoWriter(OUT_FILE_NAME, cv_fourcc('X', 'V', 'I', 'D'), 30, (cols, rows), True) #avi
x = np.arange(0, 10, 0.1)
fig=plt.figure(figsize=(12, 8))
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(224)
ax4 = fig.add_subplot(223)
ax1.axis([0, 10,-1.2, 1.2])
ax2.axis([0, 100, 0, 100])
ax3.axis([-1.2, 1.2,0, 10])
ax4.axis([0, 100, 0, 100])
def f(x, y):
return np.sin(x) + np.cos(y)
x1 = np.linspace(0, 2 * np.pi, 100)
y1 = np.linspace(0, 2 * np.pi, 100).reshape(-1, 1)
ims = []
images=[]
for a in range(10):
fig.delaxes(ax1)
fig.delaxes(ax3)
ax1 = fig.add_subplot(221)
ax3 = fig.add_subplot(224)
y = np.sin(x - a)
line, = ax1.plot(x, y, "r")
ims.append([line])
line, = ax3.plot(y, x, "r")
ims.append([line])
x1 += np.pi / 15.
y1 += np.pi / 20.
im = ax2.imshow(f(x1, y1), animated=True)
ims.append([im])
im = ax4.pcolormesh(f(x1, y1), cmap='hsv')
ims.append([im])
fig1=plt.pause(0.001)
#Gifアニメーションのために画像をためます
plt.savefig("output/image"+str(a)+".png")
dst = cv2.imread('output/image'+str(a)+'.png')
out.write(dst) #mp4やaviに出力します
【matplotlib基本】動的グラフを書いてみる♬
<img src="http://img.youtube.com/vi/9Al1vfcMj2o/0.jpg"
※画像をクリックするとYouTube動画につながります
###・PILを使ってGifアニメーションとして出力させる
やっとたどり着いた感じ。。
【参考】
③Python, PillowでアニメーションGIFを作成、保存@note.nkmk.me
④Python PillowでPNGからGIFを作る
コードは以下のとおり、上記の動画出力の最後に以下を追加するだけで実現できました。
import glob
files = sorted(glob.glob('output/*.png'))
images = list(map(lambda file: Image.open(file), files))
images[0].save('out.gif', save_all=True, append_images=images[1:], duration=100, loop=0)
画像50枚を使って、gifアニメーションしてみると、以下のとおり。なお、100枚もやってみたが、それなりに動いた。しかし、ファイルが大きすぎてアップできなかった。
※どうもがくがくしている??
なお、環境はPillowのバージョンは以下のとおり、3.4以上で対応している。
【参考】
⑤Creating a multiframe image object #2401@python-pillow/Pillow
This makes sense, as append_images was added in Pillow 3.4. So I recommend that you upgrade.
ということで、windows10でも、以下のコマンドで...一応Pillowのバージョンは3.3.1からUpgradeできたようです。
>pip install -U Pillow
>python
>>> import PIL
>>> print(PIL.__version__)
5.4.1
###まとめ
・PILとimagemagickでGifアニメーションに出力できた
・PILの方が使い勝手は良い
・matplotlibのanimationは単独程度の低負荷な場合は使えるが、普通にアニメーションさせた方が性能は良い
・よくよく見ると、mp4などでの出力(元画像のパラパラ動画)に比較して、Gifアニメーションの動画は途中余分に変な動作をしているが、原因は不明である。
⇒おまけに追記した。
・いよいよ、次回はFFT,STFT,そしてWavelet変換のアプリを作ろう
###おまけ
以下、ちゃんと出力できなかったが、ダウンロードして動きそうな気配もあるので、記載しておく
images2gif/images2gif.py
使い方は、
python3で3dのgifを作成
Animated 3-D Plots in Python
###追記(30/1/2019)
どうもガクガクする理由が正しくソートされていないことが原因だったので、スマートなコードはあきらめて、以下のように明示的に読み込んだ。
⇒スムーズに100枚読込んで表示できた!
from PIL import Image, ImageDraw
images = []
for i in range(40):
im = Image.open('output/image' + str(i)+ '.jpg')
images.append(im)
images[0].save('out_original40.gif', save_all=True, append_images=images[1:40], duration=40, loop=0)
100枚、50枚も綺麗に動いたが、40枚しかアップできないのでそれを貼っておく。
もともとの動画もほとんど同じコードでGifアニメーション作成できたので貼っておく
※こちらは100枚貼れました
from PIL import Image, ImageDraw
images = []
for i in range(100):
im = Image.open('output_ori/image' + str(i)+ '.png')
images.append(im)
images[0].save('out_original_ori100.gif', save_all=True, append_images=images[1:100], duration=40, loop=0)