2012-01-10 58 views
4

我想製作一些電影中的一些繪製點移動以進行基本的交通模擬。雖然繪製需要永久 - 〜10幀需要7秒!那是怎麼回事?優化matplotlib pyplot:繪製許多小圖

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

請注意'plt.plot()'有一個返回值。這是對藝術家的處理,所以請保留它並重新使用它。 – wim 2012-01-10 03:29:28

回答

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) 
2

您可能感興趣的matplotlib的(1.1.0)新animation feature。下面是他們網站的一個例子,演示瞭如何製作一個簡單的動畫:

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')