2013-01-16 105 views
1

這是我的腳本至今:Python - 如何爲我的散點圖創建動畫?

import numpy as np 
import matplotlib.pyplot as plt 
import random 
t=0 
r=3.0 
n=0 
A=[] 
for x in range(10): 
    for y in range(10): 
    A.append([random.uniform(0,1),random.uniform(0,1)]) 
for m in range(len(A)): 
    plt.plot(A[m][0],A[m][1], "x", color="blue") 
plt.show() 
while n<=100: 
    for m in range(len(A)): 
    A[m][0]=r*A[m][0]*(1-A[m][0]) 
    A[m][1]=r*A[m][1]*(1-A[m][1]) 
    for m in range(len(A)): 
    plt.plot(A[m][0],A[m][1], "x", color="blue") 
    plt.show() 
    n+=1 

我想現在要做的是動畫,所以我不必每次爲蟒蛇重新計算的告訴​​我下一個圖像時關閉情節。相反,它應該給我一個每5秒說一個新的情節。我做這件事的最好方法是什麼?

回答

1

使用plt.ion()可啓用交互式繪圖(不會在打開繪圖窗口時停止執行),然後使用plt.clf()清除繪圖。

工作示例是:

import numpy as np 
import matplotlib.pyplot as plt 
plt.ion() 

import random 
t=0 
r=3.0 
n=0 
A=[] 
for x in range(10): 
    for y in range(10): 
     A.append([random.uniform(0,1),random.uniform(0,1)]) 

for m in range(len(A)): 
    plt.plot(A[m][0],A[m][1], "x", color="blue") 
    plt.draw() 
plt.pause(1) 

while n<=100: 
    for m in range(len(A)): 
     A[m][0]=r*A[m][0]*(1-A[m][0]) 
     A[m][1]=r*A[m][1]*(1-A[m][1]) 
    for m in range(len(A)): 
     plt.plot(A[m][0],A[m][1], "x", color="blue") 
    plt.draw() 
    plt.pause(1) 
    plt.clf() 

必須使用plt.draw()迫使GUI立即更新和plt.pause(t)打破了t秒。實際上,我不太清楚你想如何在動畫方面處理腳本的兩部分(包含劇情命令的兩個循環),但是希望我的代碼能夠以正確的方式指導你。

備註

首先,我建議編碼蟒蛇時要堅持一些約定。使用4空格縮進,這使得您的代碼更具可讀性。其次,我建議使用numpy作爲數組。您可以導入它,但不使用它。這使你的代碼更快。 第三也是最後一個,你知道matplotlib的簽名plot(x,y,"bx")嗎?我認爲這非常方便。

+1

謝謝!幾個變化,它正是我想要的。並且也非常感謝這些提示,numpy仍舊從早期版本中遺留下來,當我使用numpy.linspace時,我忘記刪除import numpy部分。 – HansFritz

7

您可以使用matplotlib.animation包:

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.animation as animation 
import random 

t=0 
r=3.0 
n=0 
A=[] 

for x in range(10): 
    for y in range(10): 
     A.append([random.uniform(0,1),random.uniform(0,1)]) 
A = np.array(A).transpose() 

fig = plt.figure() 
line, = plt.plot(A[0],A[1], "x", color="blue") 

def update(): 
    for i in range(100): 
     A[0], A[1] = r*A[0]*(1-A[0]), r*A[1]*(1-A[1]) 
     yield A 

def draw(data): 
    line.set_xdata(data[0]) 
    line.set_ydata(data[1]) 
    return line, 

ani = animation.FuncAnimation(fig, draw, update, interval=1000, blit=False) 

plt.show() 

update功能是發電機,該發電機產生的後續步驟的數據,而draw是更新繪圖數據並返回的功能。

+0

有一點需要注意的是,動畫模塊會保留一個結果副本,以便取消'update',這可能會導致內存問題,如果您的幀很大。 – tacaswell

+0

+1使用'動畫' – tacaswell

0

我建議使用matplotlib的面向對象接口,很好地總結在artist tutorial

有了這個,你會得到更好地控制圖中的行爲,並可以簡單地重新繪製你的循環中的情節:

import numpy as np 
import matplotlib.pyplot as plt 
import random 
from time import sleep 
t=0 
r=3.0 
n=0 
A=[] 
for x in range(10): 
    for y in range(10): 
     A.append([random.uniform(0,1),random.uniform(0,1)]) 
fig = plt.figure() 
ax = fig.add_subplot(111) 
for m in range(len(A)): 
    ax.plot(A[m][0],A[m][1], "x", color="blue") 
fig.show() 
sleep(1) 
while n<=100: 
    for m in range(len(A)): 
     A[m][0]=r*A[m][0]*(1-A[m][0]) 
     A[m][1]=r*A[m][1]*(1-A[m][1]) 
    ax.clear() 
    for m in range(len(A)): 
     ax.plot(A[m][0],A[m][1], "x", color="blue") 
    fig.canvas.draw() 
    sleep(1) 
    n+=1 

從腳本的主要變化是使用fig.show代替plt.show後更新與fig.canvas.draw圖改變數據。