新しいバージョンの Matplotlib を使用している場合は、定型コードの一部を削減するのに役立つanimations.FuncAnimation
クラスがあります。(例については、このページを参照してください。) かなり高速です (~ 52 フレーム/秒):
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import timeit
clock = timeit.default_timer
fig, ax = plt.subplots()
alphab = ['A', 'B', 'C', 'D', 'E', 'F']
frequencies = [1, 44, 12, 11, 2, 10]
pos = np.arange(len(alphab))
width = 1.0 # gives histogram aspect to the bar diagram
ax.set_xticks(pos + (width / 2))
ax.set_xticklabels(alphab)
rects = plt.bar(pos, frequencies, width, color='r')
start = clock()
def animate(arg, rects):
frameno, frequencies = arg
for rect, f in zip(rects, frequencies):
rect.set_height(f)
print("FPS: {:.2f}".format(frameno / (clock() - start)))
def step():
for frame, bin_idx in enumerate(np.linspace(0,1000000,100000000), 1):
#Here we just change the first bin, so it increases through the animation.
frequencies[0] = bin_idx
yield frame, frequencies
ani = animation.FuncAnimation(fig, animate, step, interval=10,
repeat=False, blit=False, fargs=(rects,))
plt.show()
新しいバージョンの Matplotlib を持っていない場合は、古い方法でこれを行うことができます。少し遅いです (~ 45 フレーム/秒):
plt.bar
ループの繰り返しごとに呼び出さないでください。rects
代わりに、一度だけ呼び出し、戻り値を保存してから、ループの後続の繰り返しでset_height
それらの高さを変更するために呼び出します。rects
このトリック (およびその他) は、Matplotlib アニメーション クックブックで説明されています。
import sys
import matplotlib as mpl
mpl.use('TkAgg') # do this before importing pyplot
import matplotlib.pyplot as plt
import numpy as np
import timeit
clock = timeit.default_timer
fig, ax = plt.subplots()
alphab = ['A', 'B', 'C', 'D', 'E', 'F']
frequencies = [1, 44, 12, 11, 2, 10]
pos = np.arange(len(alphab))
width = 1.0 # gives histogram aspect to the bar diagram
ax.set_xticks(pos + (width / 2))
ax.set_xticklabels(alphab)
def animate():
start = clock()
rects = plt.bar(pos, frequencies, width, color='r')
for frameno, bin_idx in enumerate(np.linspace(0,1000000,100000000), 2):
#Here we just change the first bin, so it increases through the animation.
frequencies[0] = bin_idx
# rects = plt.bar(pos, frequencies, width, color='r')
for rect, f in zip(rects, frequencies):
rect.set_height(f)
fig.canvas.draw()
print("FPS: {:.2f}".format(frameno / (clock() - start)))
win = fig.canvas.manager.window
win.after(1, animate)
plt.show()
比較のためplt.clf
に、元のコードに追加すると、私のマシンでは毎秒約 12 フレームに達します。
タイミングに関するいくつかのコメント:
ループを通過するたびに非常にわずかな時間差を計算しても、正確な測定値は得られません。の時間分解能はtime.time()
、少なくとも私のコンピュータでは十分ではありません。1 つの開始時間を測定し、開始時間と現在の時間の間の大きな時間差を計算してから、フレーム数で割ると、より正確な測定値が得られます。
にも変更time.time
しましたtimeit.default_timer
。この 2 つは Unix コンピュータでは同じですが、Windows マシンでtimeit.default_timer
は に設定されています。time.clock
したがってtimeit.default_timer
、プラットフォームごとにより正確なタイマーを選択します。