2017-10-20 39 views
2

J'ai un mis en œuvre jeu de la vie de Conway comme:Comment puis-je animer un ensemble de points avec matplotlib?

def neighbors(point): 
    x, y = point 
    for i, j in itertools.product(range(-1, 2), repeat=2): 
     if any((i, j)): 
      yield (x + i, y + j) 

def advance(board): 
    newstate = set() 
    recalc = board | set(itertools.chain(*map(neighbors, board))) 

    for point in recalc: 
     count = sum((neigh in board) 
       for neigh in neighbors(point)) 
     if count == 3 or (count == 2 and point in board): 
      newstate.add(point) 

    return newstate 

Je veux visualiser le résultat, j'ai donc essayé de modifier l'exemple de Matplotlib animation example:

glider = set([(0, 0), (1, 0), (2, 0), (0, 1), (1, 2)]) 

fig, ax = plt.subplots() 

x, y = zip(*glider) 
mat, = ax.plot(x, y, 'o') 

def animate(i): 
    glider = advance(glider) 
    x, y = zip(*glider) 
    mat.set_data(x, y) 
    return mat, 

ani = animation.FuncAnimation(fig, animate, interval=50) 
plt.show() 

mais que les parcelles juste the initial points.

+0

Vous pourriez être intéressé par d'autres implémentations matplotlib du jeu de la vie, comme [celui-ci] (https://stackoverflow.com/questions/45653550/ arrêt-animation-conways-jeu-de-vie) ou [celui-ci] (https://stackoverflow.com/questions/46196346/why-does-my-game-of-life-simulation-slow-down-to- a-crawl-within-seconds-matplot). – ImportanceOfBeingErnest

Répondre

3

Le code que vous avez doit effectivement produire une erreur. Le problème est que vous référencez glider avant de l'assigner.

Attention à la portée locale des variables dans les fonctions python. Par exemple. essayez

a = 0 
def f(): 
    a = a + 1 
f() 

qui vous donnera la même erreur.

Dans votre code du jeu de la vie de Conway, vous pouvez contourner cela en mettant glider à la portée mondiale, global glider. Assurez-vous également que vos limites d'axes permettent de voir l'animation.

Exemple complet:

import itertools 
import matplotlib.pyplot as plt 
import matplotlib.animation as animation 

def neighbors(point): 
    x, y = point 
    for i, j in itertools.product(range(-1, 2), repeat=2): 
     if any((i, j)): 
      yield (x + i, y + j) 

def advance(board): 
    newstate = set() 
    recalc = board | set(itertools.chain(*map(neighbors, board))) 

    for point in recalc: 
     count = sum((neigh in board) 
       for neigh in neighbors(point)) 
     if count == 3 or (count == 2 and point in board): 
      newstate.add(point) 

    return newstate 

glider = set([(0, 0), (1, 0), (2, 0), (0, 1), (1, 2)]) 

fig, ax = plt.subplots() 

x, y = zip(*glider) 
mat, = ax.plot(x, y, 'o') 

def animate(i): 
    global glider 
    glider = advance(glider) 
    x, y = zip(*glider) 
    mat.set_data(x, y) 
    return mat, 

ax.axis([-15,5,-15,5]) 
ani = animation.FuncAnimation(fig, animate, interval=50) 
plt.show() 

enter image description here

+0

Par curiosité @ImportanceOfBeingness, comment avez-vous généré ce gif? –

+1

@ReblochonMasqueVous pouvez [enregistrer n'importe quelle animation] (http://matplotlib.org/api/_as_gen/matplotlib.animation.Animation.html#matplotlib.animation.Animation.save) dans ce cas: 'ani.save (" output. gif "écrivain =" imagemagick ")'. – ImportanceOfBeingErnest

+0

Merci beaucoup! –