環境
- Mac mini(M1) Big Sur
- Python 3.9.6(arm64)
- numpy 1.21.1
- matplotlib 3.4.3
- PyQtGraph 0.12.2
目標
高速レンダリングを活かしてmatplotlibよりもフレーム数の多いアニメーションを描画する.
実習
以下を読み込んであることを前提とします.
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
import pyqtgraph as pg
from pyqtgraph import QtCore
np.random.seed(39)
x = np.linspace(0, 10, 100)
t = np.linspace(0, 10, 1000)
x, t = np.meshgrid(x, t)
y = np.cos(x - 100*t)
matplotlib.animation
matplotlibのアニメーションはまだよく分かっていないため,こちらの質疑を参考にしました.
# fig, ax = plt.subplots()
win = pg.plot()
# ims = []
curve = win.plot()
'''
for I in range(Len(t)):
axes = ax.scatter(x[I], y[I], c='k')
title = ax.text(
0.5, 1.01,
f'time = {t[I,0]:.3f}',
ha='center', va='bottom',
transform=ax.transAxes,
fontsize='large',
)
ims.append([axes, title])
'''
idx = 0
def update():
global curve, win, idx, x, t, y
curve.setData(x[idx], y[idx])
win.setLabels(title=f'time = {t[idx,0]:.3f}')
idx = (idx+1)%len(t)
# ani = animation.ArtistAnimation(fig, ims, interval=1)
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(1)
# ani.savefig('animation.gif')
pg.exec()
$x$軸方向に進行する波動が描画できるはずです.PyQtGraphだと実行と共にグラフが表示されるのに対して,matplotlibは23分もかかりました.画像貼ろうとすると重すぎるのかエラーが出るのでありません.
PyQtGraphでの注意点として最初にwin = pg.plot()
でPlotItem
をインスタンス化した後に,curve = win.plot()
でPlotDataItem
をインスタンス化しておく必要があります.前回調べたようにPlotDataItem
は描画される線や点を保持します.そしてupdate
を呼び出すごとにsetData
で中身を更新していく仕掛けです.この更新作業はpg.QtCore.QTimre
がやってくれます.また最後のstart(1)
はおそらくフレーム間隔に1 msを設定できているはずです.フレームレートの計測ができてないので実際は分かりませんが,少なくともこの数字を大きくするとアニメーションの再生速度が遅くなりました.
ani.savefig()
どうにもPyQtGraph単体だと無理っぽい.こちらの情報に従ってffmpegを試したいです.
結論
描画も再生速度も申し分なし.保存は一手間要りそう.
希望
- 全フレームを一度書き出してからffmpegでエンコードしたい