Pythonのグラフ描画ライブラリMatplotlib
ではアニメーションも作成できますが、初めての人には少し複雑です…。
そこで、今回は
Matplotlib
でアニメーションを描きたいけど、よくわからない!FuncAnimation
で更新用関数作るって何?意味不明!!
という方のために、
FuncAnimation
でアニメーションを作成する超基本- 更新用関数
update()
の作成方法
について、必要な設定や引数がすぐわかるように、画像・サンプルコード付きで紹介していきます!
- Matplotlibでアニメーションを作成する2つの方法
- Jupyter Notebookの場合の注意点
- 【入門編】FuncAnimationでアニメーション作成
- 【応用編】色を変更するアニメーション
- 【応用編】テキスト/タイトルを変更するアニメーション
- アニメーションの保存方法
- Matplotlibのアニメーションまとめ
Matplotlibでアニメーションを作成する2つの方法
Matplotlib
でアニメーションを作成するには、matplotlib.animation
モジュールのクラスを使用します。
ArtistAnimation
クラスかFuncAnimation
クラスを使いますが、それぞれ次のような特徴があります。
ArtistAnimation
クラス:- 事前にグラフ要素を複数作成
- それらを組み合わせてアニメーションにする
FuncAnimation
クラス:- 事前にグラフ更新用関数を作成
- 関数を実行しながらアニメーションにする
FuncAnimation
は、関数を実行しながらアニメーションを作成します。
そのため、表示の面では効率が良いですが、設定は少し複雑です。
効率よりも手軽さ重視の場合は、次の記事のArtistAnimation
を使用してみてください。
Jupyter Notebookの場合の注意点
Jupyter Notebookの場合、%matplotlib inline
でMatplotlib
を読み込んでも、アニメーションは表示できません。
Jupyter Notebook上でアニメーションを表示するには、Matplotlib
読み込み時に次のコードを実行します。
%matplotlib notebook
from matplotlib import pyplot as plt
%matplotlib notebook
で読み込むと、Matplotlib
のバックエンド(内部処理方法)が変更されて、動画を表示できるようになります。
%matplotlib
について、詳しく知りたい方は次の記事をチェックしてください。
【入門編】FuncAnimationでアニメーション作成
アニメーション作成では、
FuncAnimation
クラスのanim
オブジェクトを作成すること
が一つ目のゴールになります。
from matplotlib.animation import FuncAnimation
anim = FuncAnimation(fig, update)
ArtistAnimation
の必須引数の意味は次の通りです。
引数名 | 解説 |
---|---|
fig |
アニメーションを描くfigure |
update |
アニメーション更新用関数 |
FuncAnimation
では、update()
関数の作成がポイントになります。
update()
関数は、一度実行するとアニメーションが1フレーム進むような関数として定義します。
下図のようにupdate()
をもとにanim
オブジェクトを作成して、アニメーション化します。
FuncAnimationの基本形
基本的には次の手順を踏みます。
- 必要なモジュールの読み込み
- グラフ領域の作成 ⇒
fig
,ax
の準備 - グラフの初期設定 ⇒ アニメーション化するグラフ要素の用意など
- 更新用関数
update()
の作成 - アニメーション化 ⇒
FuncAnimation
インスタンス作成
簡単なアニメーションを例に、手順を見ていきましょう。
# 1.グラフ領域の作成
%matplotlib notebook
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
# 2.グラフ領域の作成
fig, ax = plt.subplots()
# 3. グラフの初期設定
my_line, = ax.plot([], [])
r = 1
ax.set_xlim(-r, r)
ax.set_ylim(-r, r)
ax.set_aspect('equal') # グラフのアスペクト比を1:1に設定
# 4. グラフ更新用関数の作成
def update(i):
theta =np.deg2rad(i)
x = [0, r*np.cos(theta)]
y = [0, r*np.sin(theta)]
my_line.set_data(x,y)
# 5. アニメーション化
anim = FuncAnimation(fig, update)
plt.show()
これを実行すると次のようなアニメーションが出力されます。
ポイントは、
- 3. グラフの初期設定 ⇒ アニメーション化するグラフ要素の用意など
- 4. グラフ更新用関数
update
の作成
です。
これらを詳しく見ていきましょう。
グラフの初期設定
グラフの初期設定では、
- アニメーション化するグラフ要素のオブジェクト作成
- 軸目盛等の設定
を行います。
作成したグラフ要素のオブジェクトは、グラフ更新関数update()
内で使用します。
my_line, = ax.plot([], [])
また、軸目盛等も初期設定時に、確定させます。
r = 1
ax.set_xlim(-r, r)
ax.set_ylim(-r, r)
ax.set_aspect('equal') # グラフの縦横比を1:1に設定
アニメーション実行時、軸目盛等は自動で調整されないので、初期設定で済ませておく必要があります。
軸周りの設定は、次の記事で解説しています。詳しく知りたい方はチェックしてください。
グラフ更新用関数の作成
グラフ更新用関数の基本形は次の通りです。
def update(frame):
# 更新内容
# グラフの更新やテキストの更新など
frame
の内容は、FuncAnimation
のオプショナル引数で設定できます。
デフォルトのframe
の内容は、
- 1フレームごとに1ずつ増える整数
- 1フレーム目:
frame = 0
- 2フレーム目:
frame = 1
… - nフレーム目:
frame = n-1
- (上限はなく、強制終了するまで無限に増える)
- 1フレーム目:
となっています。
frame
の値が1ずつ増加することを利用して、グラフを更新する関数を作成します。
例では、1フレームごとに1°ずつ円周上の点を移動させています。
frame
の名前は自由に変更OKです。ここでは、i
としています。
def update(i):
theta =np.deg2rad(i)
x = [0, r*np.cos(theta)]
y = [0, r*np.sin(theta)]
my_line.set_data(x,y)
このとき、プロットのデータの更新は、my_line.set_data(x,y)
を使用しています。
グラフ要素の.set_XXX()
を適切に利用することが、FuncAnimation
のポイントです。
【応用編】色を変更するアニメーション
ax.plot()
で作成したオブジェクトの使用頻度が高そうなメソッドを紹介します。
メソッド | 内容 |
---|---|
.set_data(x, y) |
データをx , y に変更 |
.set_color(color) |
グラフの色をcolor に変更(線とプロット両方) |
.set_markeredgecolor(color) |
プロット周囲の色をcolor に変更 |
.set_markerfacecolor(color) |
プロット内部の色をcolor に変更 |
アニメーションでは色を変更させることが多いので、カラーマップを使用した色の変更例を紹介します。
# 3. 初期プロットの作成
my_line, = ax.plot([], [],color="gray", linestyle="--", linewidth=1, marker="o", markeredgecolor="None")
r = 1
ax.set_xlim(-r, r)
ax.set_ylim(-r, r)
ax.set_aspect('equal') # グラフのアスペクト比を1:1に設定
cm = plt.get_cmap("winter")
# 3. グラフ更新用関数
def update(i):
theta = np.deg2rad(i)
x = [0, r*np.cos(theta)]
y = [0, r*np.sin(theta)]
my_line.set_data(x,y)
my_line.set_markerfacecolor(cm(i%360/360))
# 4. アニメーション化
anim = FuncAnimation(fig, update, frames=360, interval=10)
plt.show()
次のような動画が出力されます。
ポイントとなるのは以下の2行です。
- カラーマップの準備:
cm = plt.get_cmap("winter")
- 色の設定:
my_line.set_markerfacecolor(cm(i%360/360))
更新用関数update()
の中で、i
に応じてカラーマップの値を設定するようにしています。
カラーマップを含めた色の詳細については、こちらの記事を参考にしてください。
【応用編】テキスト/タイトルを変更するアニメーション
ax.text()
でテキストオブジェクトを準備すれば、アニメーションに内にテキストを含めることも可能です。
my_text = ax.text(x, y, s)
text
オブジェクトを作成して、.set_XXX()
で座標や内容を更新します。
メソッド | 内容 |
---|---|
.set_x(x) |
テキストのx 座標設定 |
.set_y(y) |
テキストのy 座標設定 |
.set_text(s) |
表示する文字列をs に設定 |
グラフのタイトルは、ax.set_title()
を使用すると便利です。
my_text = ax.set_title(s)
内容の更新は、テキスト同様に.set_text(s)
です。
以下で、テキストとタイトルを変更するアニメーション例を紹介します。
# 3. 初期プロットの作成)
my_line, = ax.plot([], [],color="gray", linestyle="--", linewidth=1, marker="o", markeredgecolor="None")
r = 1
ax.set_xlim(-r, r)
ax.set_ylim(-r, r)
ax.set_aspect('equal') # グラフのアスペクト比を1:1に設定
my_title = ax.set_title("")
my_text = ax.text(r, 0, "")
# 4. グラフ更新用関数
def update(i):
theta = np.deg2rad(i)
x = [0, r*np.cos(theta)]
y = [0, r*np.sin(theta)]
my_line.set_data(x,y)
my_title.set_text(f"Plot@ i={i}")
my_text.set_x(x[1])
my_text.set_y(y[1])
my_text.set_text(f"theta={i%360}°")
# 5. アニメーション化
anim = FuncAnimation(fig, update, interval=10)
plt.show()
次のような動画が出力されます。
アニメーションの保存方法
保存には、作成したanim
オブジェクトのsave
メソッドを使用します。
anim.save("ファイル名.拡張子")
ただし、保存形式によってそれぞれ必要な準備・設定があります。
ここでは、
- mp4形式
- gif形式
で保存する方法を紹介します。
mp4で保存
mp4で保存するためには、ffmpeg
という外部ライブラリを使用します。
使用環境に応じて、conda
またはpip
でインストールする必要があります。
conda install ffmpeg
pip install ffmpeg-python
ffmpeg
をインストールできれば、
anim.save("ファイル名.mp4")
で保存可能です。
anim = ArtistAnimation(fig, artists)
anim.save("sin_anim.mp4")
# ⇒ カレントフォルダにmp4出力
ffmpeg
をインストールしておけば、比較的簡単に出力できますね。
gifで保存
アニメーションをgifで保存するためには、pillow
という外部ライブラリを使用します。
インストールしていない場合は、conda
またはpip
でインストールする必要があります。
conda install pillow
pip install Pillow
pillow
をインストールしたら、
anim.save("ファイル名.gif", writer="pillow")
で保存可能です。
anim = ArtistAnimation(fig, artists)
anim.save("sin_anim.mp4")
# ⇒ カレントフォルダにgif出力
pillow
以外にも、Imagemagick
というものを使用する方法もありますが、pillow
の方が簡単に設定できます。
Matplotlibのアニメーションまとめ
FuncAnimation
クラスで、アニメーションを作成する方法を紹介しました。
- 事前にグラフ更新用関数(
update()
)を作成 - 関数を実行しながらアニメーションにする
というところがポイントです!
Matplotlib
のもう一つのアニメーション方法ArtistAnimation
クラスでは、次のように設定を行います。
- 事前にグラフ要素を複数作成
- それらを組み合わせてアニメーションにする
FuncAnimation
に比べて、設定が単純なので、ちょっとしたアニメーションを作成するときには、こちらを使用することも検討してみましょう。
詳細はこちらの記事で解説しています。
Matplotlib
マスターを目指す皆さんへの次のおススメコンテンツはこちらです!
Twitter@YutaKaでは、ほぼ毎日pythonに関する情報を発信しています。
気楽にツイートしているので、気軽にフォローしてください!