首先,尽管这不会改变性能,考虑优化你的代码,类似于以下方式:
import matplotlib.pyplot as plt
import numpy as np
import time
x = np.arange(0, 2*np.pi, 0.01)
y = np.sin(x)
fig, axes = plt.subplots(nrows=6)
styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
lines = [ax.plot(x, y, style)[0] for ax, style in zip(axes, styles)]
fig.show()
tstart = time.time()
for i in xrange(1, 20):
for j, line in enumerate(lines, start=1):
line.set_ydata(np.sin(j*x + i/10.0))
fig.canvas.draw()
print 'FPS:' , 20/(time.time()-tstart)
通过上述示例,我获得了大约10fps的帧率。
顺便提一下,根据您的确切用例,matplotlib可能不是一个很好的选择。它面向出版质量的图形,而不是实时显示。
但是,有很多方法可以加速此示例。
这个效果如此之慢,主要有两个原因。
1)调用
fig.canvas.draw()
会重新绘制所有内容。 它是瓶颈。 在您的情况下,您不需要重新绘制诸如轴边界、刻度标签等的内容。
2)在您的情况下,有许多子图和大量的刻度标签。 这些需要很长时间才能绘制。
这两者都可以通过使用blitting来解决。
为了有效地进行blitting,您必须使用特定于后端的代码。 实际上,如果您真的担心平滑动画,通常会将matplotlib绘图嵌入某种GUI工具包中,因此这不是什么问题。
然而,如果不了解更多关于您正在做什么的信息,我无法在这方面为您提供帮助。
尽管如此,仍有一种与GUI无关的方法,速度仍然相对较快。
import matplotlib.pyplot as plt
import numpy as np
import time
x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)
fig, axes = plt.subplots(nrows=6)
fig.show()
fig.canvas.draw()
styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
def plot(ax, style):
return ax.plot(x, y, style, animated=True)[0]
lines = [plot(ax, style) for ax, style in zip(axes, styles)]
backgrounds = [fig.canvas.copy_from_bbox(ax.bbox) for ax in axes]
tstart = time.time()
for i in xrange(1, 2000):
items = enumerate(zip(lines, axes, backgrounds), start=1)
for j, (line, ax, background) in items:
fig.canvas.restore_region(background)
line.set_ydata(np.sin(j*x + i/10.0))
ax.draw_artist(line)
fig.canvas.blit(ax.bbox)
print 'FPS:' , 2000/(time.time()-tstart)
这让我达到了约200帧每秒的速度。
为了使这更加方便,最近版本的matplotlib中有一个animations
模块。
以下是一个例子:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
x = np.arange(0, 2*np.pi, 0.1)
y = np.sin(x)
fig, axes = plt.subplots(nrows=6)
styles = ['r-', 'g-', 'y-', 'm-', 'k-', 'c-']
def plot(ax, style):
return ax.plot(x, y, style, animated=True)[0]
lines = [plot(ax, style) for ax, style in zip(axes, styles)]
def animate(i):
for j, line in enumerate(lines, start=1):
line.set_ydata(np.sin(j*x + i/10.0))
return lines
ani = animation.FuncAnimation(fig, animate, xrange(1, 200),
interval=0, blit=True)
plt.show()
fig.canvas.draw_idle()
而不是fig.canvas.draw()
对我有用。 - Nirmal