Trước hết, (mặc dù điều này sẽ không thay đổi hiệu suất), hãy xem xét xóa mã của bạn, tương tự như sau:
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)
Với ví dụ trên, tôi nhận được khoảng 10 khung hình / giây.
Chỉ cần một lưu ý nhanh, tùy thuộc vào trường hợp sử dụng chính xác của bạn, matplotlib có thể không phải là một lựa chọn tuyệt vời. Nó hướng tới các số liệu chất lượng xuất bản, không phải hiển thị thời gian thực.
Tuy nhiên, có rất nhiều điều bạn có thể làm để tăng tốc ví dụ này.
Có hai lý do chính khiến việc này diễn ra chậm như vậy.
1) Gọi điện fig.canvas.draw()
vẽ lại mọi thứ . Đó là nút thắt cổ chai của bạn. Trong trường hợp của bạn, bạn không cần phải vẽ lại những thứ như ranh giới trục, đánh dấu nhãn, v.v.
2) Trong trường hợp của bạn, có rất nhiều ô phụ với rất nhiều nhãn đánh dấu. Những thứ này mất nhiều thời gian để vẽ.
Cả hai điều này đều có thể được khắc phục bằng cách sử dụng blting.
Để xóa hiệu quả, bạn sẽ phải sử dụng mã phụ trợ cụ thể. Trong thực tế, nếu bạn thực sự lo lắng về các hình ảnh động mượt mà, bạn thường nhúng các ô matplotlib vào một số loại bộ công cụ gui, vì vậy đây không phải là vấn đề nhiều.
Tuy nhiên, nếu không biết thêm một chút về những gì bạn đang làm, tôi không thể giúp bạn ở đó.
Tuy nhiên, có một cách trung lập để làm điều đó vẫn nhanh hợp lý.
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()
# We need to draw the canvas before we start animating...
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)]
# Let's capture the background of the figure
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)
Điều này mang lại cho tôi ~ 200 khung hình / giây.
Để làm cho điều này thuận tiện hơn một chút, có một animations
mô-đun trong các phiên bản gần đây của matplotlib.
Ví dụ:
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
# We'd normally specify a reasonable "interval" here...
ani = animation.FuncAnimation(fig, animate, xrange(1, 200),
interval=0, blit=True)
plt.show()