matplotlib.animation
#
アニメーション#
Matplotlib でライブ アニメーションを作成する最も簡単な方法は、いずれかの
Animation
クラスを使用することです。
アニメーションの基本クラス。 |
|
関数funcを繰り返し呼び出してアニメーションを作成します。 |
|
|
どちらの場合も、インスタンス オブジェクトへの参照を維持することが重要です。Animation
アニメーションは、オブジェクトが唯一の参照を保持するタイマー (通常はホスト GUI フレームワークから) によって進められます。オブジェクトへの参照を保持していない場合、Animation
オブジェクト (およびタイマー) がガベージ コレクションされ、アニメーションが停止します。
アニメーションを保存するには、、、または を使用Animation.save
しAnimation.to_html5_video
ますAnimation.to_jshtml
。
サポートされているムービー形式の詳細については、以下のヘルパー クラスを参照してください。
FuncAnimation
#
の内部の仕組みはFuncAnimation
多かれ少なかれ次のとおりです。
for d in frames:
artists = func(d, *fargs)
fig.canvas.draw_idle()
fig.canvas.start_event_loop(interval)
「ブリッティング」の処理 (ライブ パフォーマンスを劇的に改善するため)、ノンブロッキング、GUI イベント ループの開始/停止の繰り返し、繰り返しの処理、複数のアニメーション化された軸、およびアニメーションをムービー ファイルに簡単に保存するための詳細が含まれています。
「ブリッティング」は、コンピュータ グラフィックスの標準的な手法です。一般的な要点は、既存のビット マップ (この場合はほとんどラスタライズされた図) を取得し、その上にもう 1 人のアーティストを「ブリット」することです。したがって、保存された「クリーンな」ビットマップを管理することで、各フレームで変化する少数のアーティストのみを再描画できるため、かなりの時間を節約できる可能性があります。( を渡すことによってblit=True
) ブリッティングを使用すると、 のコア ループは
FuncAnimation
もう少し複雑になります。
ax = fig.gca()
def update_blit(artists):
fig.canvas.restore_region(bg_cache)
for a in artists:
a.axes.draw_artist(a)
ax.figure.canvas.blit(ax.bbox)
artists = init_func()
for a in artists:
a.set_animated(True)
fig.canvas.draw()
bg_cache = fig.canvas.copy_from_bbox(ax.bbox)
for f in frames:
artists = func(f, *fargs)
update_blit(artists)
fig.canvas.start_event_loop(interval)
もちろん、これは多くの詳細を省略しています (図のサイズ変更や完全な再描画時に背景を更新するなど)。ただし、うまくいけば、この最小限の例は、内部で と がどのように使用されているinit_func
か、および「ブリッティング」がどのように機能するかの理論を示しています。func
FuncAnimation
期待される署名func
とは、帳簿の保持とロジックのプロットから除外するのinit_func
は非常に簡単ですFuncAnimation
が、これは、渡す呼び出し可能なオブジェクトが、どのアーティストに取り組んでいるかを知っている必要があることを意味します。これを処理するには、さまざまな複雑さとカプセル化のいくつかのアプローチがあります。スクリプトの場合に非常にうまく機能する最も簡単な方法は、グローバル スコープでアーティストを定義し、Python に処理を任せることです。例えば
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = ax.plot([], [], 'ro')
def init():
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-1, 1)
return ln,
def update(frame):
xdata.append(frame)
ydata.append(np.sin(frame))
ln.set_data(xdata, ydata)
return ln,
ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
init_func=init, blit=True)
plt.show()
2 番目の方法は、functools.partial
アーティストを「バインド」して機能させるために使用する方法です。3 つ目の方法は、クロージャを使用して、必要なアーティストと関数を構築することです。4 番目の方法は、クラスを作成することです。
例#
ArtistAnimation
#
例#
ライタークラス#
提供されるライターは、いくつかの大きなカテゴリに分類されます。
Pillow ライターは、Pillow ライブラリに依存してアニメーションを書き込み、すべてのデータをメモリに保持します。
HTML ライターは、JavaScript ベースのアニメーションを生成します。
JavaScript ベースの HTML ムービーのライター。 |
パイプベースのライターは、キャプチャされたフレームをパイプ経由で外部プロセスにストリーミングします。パイプベースのバリアントはパフォーマンスが向上する傾向がありますが、すべてのシステムで機能するとは限りません。
パイプベースの ffmpeg ライター。 |
|
パイプベースのアニメーション gif。 |
ファイルベースのライターは、フレームごとに一時ファイルを保存し、最後に 1 つのファイルにまとめます。これらのライターは低速ですが、デバッグが容易です。
ファイルベースの ffmpeg ライター。 |
|
ファイルベースのアニメーション gif ライター。 |
ライター クラスは、同じ基礎となる から順次フレームを取得する方法を提供しますFigure
。それらはすべて、順番に呼び出す必要がある 3 つのメソッドを提供します。
setup
ライターを準備します (パイプを開くなど)。パイプベースのライターとファイルベースのライターは、 に対して異なる引数を取りますsetup()
。grab_frame
その後、一度に 1 つのフレームをキャプチャするために必要な回数呼び出すことができますfinish
ムービーをファイナライズし、出力ファイルをディスクに書き込みます。
例:
moviewriter = MovieWriter(...)
moviewriter.setup(fig, 'my_movie.ext', dpi=100)
for j in range(n):
update_figure(j)
moviewriter.grab_frame()
moviewriter.finish()
ライター クラスを ( 経由ではなく) 直接使用する場合は、コンテキスト マネージャーAnimation.save
を使用することを強くお勧めします。saving
with moviewriter.saving(fig, 'myfile.mp4', dpi=100):
for j in range(n):
update_figure(j)
moviewriter.grab_frame()
セットアップとクリーンアップが必要に応じて確実に実行されるようにします。
例#
ヘルパー クラス#
アニメーション基本クラス#
アニメーションの基本クラス。 |
|
|
ライター レジストリ#
Animation.save
モジュール レベルのレジストリが提供され、ライターの名前とクラスをマッピングして、ライター インスタンスの代わりに文字列を渡すことができ
ます。
人間が読める名前による利用可能なライター クラスのレジストリ。 |
ライター基本クラス#
コードの重複ベース クラスを削減するには
を呼び出してフレームを取得する方法を提供する、ムービーを作成するための抽象基本クラス |
|
映画を書くための基本クラス。 |
|
|
とミックスイン
FFMpeg 出力用の Mixin クラス。 |
|
ImageMagick 出力の Mixin クラス。 |
提供されています。
MovieWriter
新しいクラスを簡単に実装する方法については、ソース コードを参照してください。