2013-06-21 144 views
4

下面的代碼使用Python和matplotlib爲康威的生命遊戲創建了一個動畫。Python matplotlib - 在康威生命遊戲動畫中更新數據

我不知道爲什麼我必須做的:與其

grid = newGrid.copy() 
mat.set_data(grid) 

簡單:

mat.set_data(newGrid) 

如何更新與劇情相關的陣列,沒有上述複製?

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

N = 100 
ON = 255 
OFF = 0 
vals = [ON, OFF] 

# populate grid with random on/off - more off than on 
grid = np.random.choice(vals, N*N, p=[0.2, 0.8]).reshape(N, N) 

def update(data): 
    global grid 
    newGrid = grid.copy() 
    for i in range(N): 
    for j in range(N): 
     total = (grid[i, (j-1)%N] + grid[i, (j+1)%N] + 
       grid[(i-1)%N, j] + grid[(i+1)%N, j] + 
       grid[(i-1)%N, (j-1)%N] + grid[(i-1)%N, (j+1)%N] + 
       grid[(i+1)%N, (j-1)%N] + grid[(i+1)%N, (j+1)%N])/255 

     if grid[i, j] == ON: 
     if (total < 2) or (total > 3): 
      newGrid[i, j] = OFF 
     else: 
     if total == 3: 
      newGrid[i, j] = ON 

    grid = newGrid.copy() 
    mat.set_data(grid) 
    return mat 

fig, ax = plt.subplots() 
mat = ax.matshow(grid) 
ani = animation.FuncAnimation(fig, update, interval=50, 
           save_count=50) 
plt.show() 

輸出似乎是正確的 - 我可以看到滑翔機,以及其他預期的模式:

Conway's Game of Life using Python/matplotlib

回答

2

還有就是爲什麼mat.set_data()需要的newGrid副本沒有特別的理由 - 重要的是,全球grid從迭代更新到迭代:

def update(data): 
    global grid 
    newGrid = grid.copy() 

    """ 
    do your updating. this needs to be done on a copy of 'grid' because you are 
    updating element-by-element, and updates to previous rows/columns will 
    affect the result at 'grid[i,j]' if you don't use a copy 
    """ 

    # you do need to update the global 'grid' otherwise the simulation will 
    # not progress, but there's no need to copy() 
    mat.set_data(newGrid) 
    grid = newGrid 

    # # there's no reason why you couldn't do it in the opposite order 
    # grid = newGrid 
    # mat.set_data(grid) 

    # at least in my version of matplotlib (1.2.1), the animation function must 
    # return an iterable containing the updated artists, i.e. 'mat,' or '[mat]', 
    # not 'mat' 
    return [mat] 

此外,在FuncAnimation我建議通過blit=True,這樣你就不會在每一幀重新繪製背景。

+0

只是一個注意,'blit = True'在OS X上崩潰... –