Matplotlib のアニメーションが遅いという問題があります。シミュレーションの結果をアニメーション化しています。これは、時間とともに色が変化する四角形の配列で最も簡単に視覚化できます。
こちらの推奨事項に従って、ブリッティングを使用して、各フレームで変化する (ごく一部の) 四角形のみを描画しています。また、FuncAnimation を使用してこれを実装しようとしましたが、Blit=True でそれを使用すると、スクリプトの実行が大幅に遅くなります。
これは、すべての長方形を FuncAnimation に戻しているためではないかと考えているため、変更されていなくてもすべて再描画されます。フレームごとに異なるアーティストを FuncAnimation に渡す方法はありますか? 変更されたもののタプル(「アニメーション」機能のコメントアウトされたブロック)を渡そうとしましたが、一見ランダムなアニメーションフレームにつながりました...
使用する:
$ python2 [script].py blit
$ python2 [script].py anim
ありがとう!
import sys
import numpy as np
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
import matplotlib.animation as manim
def animate_data(plot_type):
"""
Use:
python2 plot_anim.py [option]
option = anim OR blit
"""
# dimension parameters
Nx = 30
Ny = 20
numtimes = 100
size = 0.5
if plot_type == "blit":
# "interactive mode on"
plt.ion()
# Prepare to do initial plot
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.set_aspect('equal', 'box')
ax.xaxis.set_major_locator(plt.NullLocator())
ax.yaxis.set_major_locator(plt.NullLocator())
# An array in which to store the rectangle artists
rects = np.empty((Nx, Ny), dtype=object)
# Generate initial figure of all green rectangles
for (i,j),k in np.ndenumerate(rects):
color = 'green'
rects[i, j] = plt.Rectangle([i - size / 2, j - size / 2],
size, size, facecolor=color, edgecolor=color)
ax.add_patch(rects[i, j])
ax.autoscale_view()
# "Old" method using fig.canvas.blit()
if plot_type == "blit":
plt.show()
fig.canvas.draw()
# Step through time updating the rectangles
for tind in range(1, numtimes):
updated_array = update_colors(rects)
for (i, j), val in np.ndenumerate(updated_array):
if val:
ax.draw_artist(rects[i, j])
fig.canvas.blit(ax.bbox)
# New method using FuncAnimate
elif plot_type == "anim":
def animate(tind):
updated_array = update_colors(rects)
# # Just pass the updated artists to FuncAnimation
# toupdate = []
# for (i, j), val in np.ndenumerate(updated_array):
# if val:
# toupdate.append(rects[i, j])
# return tuple(toupdate)
return tuple(rects.reshape(-1))
ani = manim.FuncAnimation(fig, animate, frames=numtimes,
interval=10, blit=True, repeat=False)
plt.show()
return
# A function to randomly update a few rectangles
def update_colors(rects):
updated_array = np.zeros(rects.shape)
for (i, j), c in np.ndenumerate(rects):
rand_val = np.random.rand()
if rand_val < 0.003:
rects[i, j].set_facecolor('red')
rects[i, j].set_edgecolor('red')
updated_array[i, j] = 1
return updated_array
if __name__ == "__main__":
if len(sys.argv) > 1:
plot_type = sys.argv[1]
else:
plot_type = "blit"
animate_data(plot_type)