如果您有较新版本的 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
高度。Matplotlib Animations Cookbookrects
中解释了这个技巧(和其他技巧)。
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()
——至少在我的电脑上——不够好。通过测量一个开始时间并计算开始时间与当前时间之间的较大时间差,然后除以帧数,您将获得更准确的测量结果。
我也改成time.time
了timeit.default_timer
。两者在 Unix 计算机上相同,但在 Windows 计算机上timeit.default_timer
设置为。time.clock
从而timeit.default_timer
为每个平台选择更准确的计时器。