优化matplotlib pyplot:绘制多个小图
我想制作一个简单的交通模拟动画,里面有一些点在移动。不过,绘制这些点的速度太慢了——大约10帧就要7秒!这是怎么回事呢?
这是我的Python代码:
import numpy as np
import matplotlib.pyplot as plt
import cProfile
def slowww_plot():
for i in range(10):
plt.plot(0, 0, 'bo')
plt.savefig('%03i.png' % i)
plt.clf()
plt.plot(0, 0, 'ro')
plt.savefig('%03i.png' % (i+1))
plt.clf()
cProfile.run('slowww_plot()', sort = 'cumulative'
运行后得到的结果是:
In [35]: %run test.py
2035814 function calls (2011194 primitive calls) in 7.322 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 7.322 7.322 <string>:1(<module>)
1 0.000 0.000 7.322 7.322 test.py:5(slowww_plot)
40 0.006 0.000 3.615 0.090 axes.py:821(cla)
1440/1120 0.044 0.000 3.278 0.003 axis.py:62(__init__)
20 0.000 0.000 3.049 0.152 pyplot.py:468(savefig)
20 0.000 0.000 3.049 0.152 figure.py:1077(savefig)
20 0.001 0.000 3.048 0.152 backend_bases.py:1892(print_figure)
520/360 0.015 0.000 2.523 0.007 axis.py:697(cla)
20 0.010 0.001 2.506 0.125 backend_bases.py:1791(print_png)
20 0.003 0.000 2.495 0.125 backend_agg.py:444(print_png)
520/360 0.006 0.000 2.475 0.007 axis.py:732(reset_ticks)
4340 0.172 0.000 2.373 0.001 lines.py:128(__init__)
20 0.000 0.000 2.198 0.110 pyplot.py:2449(plot)
20 0.000 0.000 2.149 0.107 pyplot.py:683(gca)
20 0.000 0.000 2.149 0.107 figure.py:1030(gca)
20 0.001 0.000 2.149 0.107 figure.py:710(add_subplot)
20 0.000 0.000 2.146 0.107 axes.py:8327(__init__)
20 0.002 0.000 2.139 0.107 axes.py:359(__init__)
20 0.000 0.000 2.075 0.104 pyplot.py:439(clf)
20 0.001 0.000 2.074 0.104 figure.py:782(clf)
20240 0.189 0.000 1.941 0.000 markers.py:114(_recache)
720/560 0.003 0.000 1.720 0.003 axis.py:1803(_get_tick)
80 0.002 0.000 1.600 0.020 axis.py:830(set_clip_path)
160 0.000 0.000 1.592 0.010 spines.py:153(cla)
720/560 0.003 0.000 1.564 0.003 axis.py:1543(_get_tick)
120 0.004 0.000 1.278 0.011 axis.py:1183(get_major_ticks)
20 1.267 0.063 1.267 0.063 {built-in method write_png}
20 0.000 0.000 1.224 0.061 backend_agg.py:394(draw)
1520/20 0.013 0.000 1.200 0.060 artist.py:53(draw_wrapper)
20 0.002 0.000 1.199 0.060 figure.py:815(draw)
20 0.002 0.000 1.175 0.059 axes.py:1866(draw)
40 0.002 0.000 1.100 0.028 axis.py:1029(draw)
10120 0.017 0.000 1.078 0.000 markers.py:132(set_fillstyle)
5780 0.013 0.000 1.032 0.000 markers.py:109(__init__)
我该怎么优化这个呢?我试过使用PdfPages
后端,还尝试从状态包装器切换到直接使用Axis.plot
,但一切还是很慢。
2 个回答
1
你可能会对matplotlib(1.1.0)新推出的动画功能感兴趣。下面是他们网站上的一个例子,展示了如何制作一个简单的动画:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def update_line(num, data, line):
line.set_data(data[...,:num])
return line,
fig1 = plt.figure()
data = np.random.rand(2, 25)
l, = plt.plot([], [], 'r-')
plt.xlim(0, 1)
plt.ylim(0, 1)
plt.xlabel('x')
plt.title('test')
line_ani = animation.FuncAnimation(fig1, update_line, 25, fargs=(data, l),
interval=50, blit=True)
line_ani.save('lines.mp4')
10
如果你想做动画,你现在的做法非常低效。
与其每次都新建一个图形,不如直接更新数据,然后重新绘制已经存在的图形。
比如说:
import matplotlib.pyplot as plt
import numpy as np
xy = 100 * np.random.random((2,10))
x, y = xy
fig, ax = plt.subplots()
points, = ax.plot(x, y, 'bo')
for i in range(10):
xy += np.random.random(xy.shape) - 0.5
points.set_data(xy)
fig.savefig('%03i.png' % i)