2010-01-21 11 views
5

Donc, je représente un réseau d'anneau à jeton (faire la simulation dans SimPy), je suis un débutant à matplotlib, mais on m'a dit que ce serait vraiment bon pour représentant visuellement ma simulation. J'ai donc fait des recherches sur Google pour trouver des formes et des lignes - en utilisant add_patch et add_line respectivement sur les axes (je crois). Alors maintenant, j'ai cette sortie qui est absolument parfait:Matplotlib en Python - Dessiner des formes et les animer

(ne peut pas publier des images encore !!) http://img137.imageshack.us/img137/7822/screenshot20100121at120.png

Mais je suis obtenir cette aide de la fonction pylab.show(), et ce que je pense Je veux est d'y parvenir en utilisant la fonction pylab.plot() afin que je puisse ensuite le mettre à jour pendant que ma simulation progresse en utilisant pylab.draw() par la suite.

Mon code est le suivant:

plab.ion() 

plab.axes() 

for circ in self.circleList: 
    plab.gca().add_patch(circ) 

for line in self.lineList: 
    plab.gca().add_line(line) 

plab.axis('scaled') 
plab.show() 

Où circleList et sont des listes contenant Liste des lignes des cercles et des lignes sur le diagramme

Je suis probablement mal compris quelque chose de simple, mais je ne peux pas réellement trouver des exemples qui ne sont pas ouvertement basés sur des graphes qui utilisent la fonction plot().


Précision:

Comment puis-je obtenir la même sortie, en utilisant pylab.plot() au lieu de pylab.show()?

Répondre

4

Reproduire votre image en utilisant la méthode du terrain:

from pylab import * 

points = [] 
points.append((-0.25, -1.0)) 
points.append((0.7, -0.7)) 
points.append((1,0)) 
points.append((0.7,1)) 
points.append((-0.25,1.2)) 
points.append((-1,0.5)) 
points.append((-1,-0.5)) 
points.append((-0.25, -1.0)) 

a_line = plot(*zip(*points))[0] 
a_line.set_color('g') 
a_line.set_marker('o') 
a_line.set_markerfacecolor('b') 
a_line.set_markersize(30) 
axis([-1.5,1.5,-1.5,1.5]) 

show() 

EDIT COMMENTAIRES SUR LA BASE

Cette bibliothèque utilise multitraitement python pour lancer l'animation matplotlib dans un processus séparé. Le processus principal utilise une file d'attente pour lui transmettre des données, ce qui met à jour l'image du tracé.

# general imports 
import random, time 
from multiprocessing import Process, Queue 

# for matplotlib 
import random 
import numpy as np 
import matplotlib 
matplotlib.use('GTKAgg') # do this before importing pylab 

import matplotlib.pyplot as plt 
from matplotlib.patches import Circle 


def matplotLibAnimate(q,points): 

    # set up initial plot 
    fig = plt.figure() 
    ax = fig.add_subplot(111) 


    circles = [] 
    for point in points: 
     ax.add_patch(Circle(point,0.1)) 

    a_line, = ax.plot(*zip(*points)) 
    a_line.set_color('g') 
    a_line.set_lw(2) 

    currentNode = None 
    def animate(currentNode = currentNode): 
     while 1: 
      newNode = q.get() 
      if currentNode: currentNode.remove() 
      circle = Circle(newNode,0.1) 
      currentNode = ax.add_patch(circle) 
      circle.set_fc('r') 
      fig.canvas.draw() 

    # start the animation 
    import gobject 
    gobject.idle_add(animate) 
    plt.show() 

#initial points 
points = ((-0.25, -1.0),(0.7, -0.7),(1,0),(0.7,1),(-0.25,1.2),(-1,0.5),(-1,-0.5),(-0.25, -1.0)) 
q = Queue() 
p = Process(target = matplotLibAnimate, args=(q,points,)) 
p.start() 

# feed animation data 
while 1: 
    time.sleep(random.randrange(4)) 
    q.put(random.sample(points,1)[0]) 

Bien sûr, après cela, je pense que vous serez mieux servi avec la solution d'image de whatnick. Je créerais ma propre interface graphique et n'utiliserais pas matplotlibs intégré dans le widget. J'animerais alors mon interface graphique en générant des fichiers PNG et en les échangeant.

+0

Mark, merci pour votre aide. Pour clarifier - ce dont j'ai besoin c'est de changer la couleur des cercles quand un jeton les contourne (ie celui avec le jeton peut être rouge et les autres verts) ceci est piloté par une bibliothèque de simulation, fonctionnant en temps réel . Je sais que vous pouvez redessiner des tracés à la volée en utilisant la méthode pylab.draw() lorsque le mode interactif est activé (pylab.ion) mais vous ne pouvez pas redessiner une image produite en utilisant pylab.show(), une seule produite par pylab.plot() (Je pense !!) J'ai donc besoin d'un moyen de changer les couleurs du cercle individuellement avant de redessiner. J'espère que cela a du sens! Merci –

+0

@Duncan, pylab.draw() bloque le reste de l'application, pour animer avec elle vous passez une fonction de rappel. Comment la fonction est transmise dépend de votre backend. Par exemple avec le GTK par défaut, vous appelez gobject.idle_add (animate); plt.show(). Je pense que votre principal problème est de savoir comment garder une simulation en cours (dans un processus ou un thread séparé) et mettre à jour la fenêtre GTK en même temps. Je vais essayer de trouver un exemple. – Mark

+0

@Duncan, voir les modifications à ma réponse. – Mark

1

La technique de base consiste à mettre à jour les données des éléments rendus en utilisant set_data. Puis appelez draw(). Voyez si vos éléments circle et line ont des fonctions set_data. Sinon, vous pouvez utiliser pyvtk. L'autre option consiste à restituer et enregistrer les tracés dans des fichiers png et à créer ensuite une animation à partir de ceux-ci.

+1

pour ajouter à cette réponse, j'ai récemment fait quelque chose comme ceci: je sauvé tous mes terrains et construit plus tard un « film » sur elle, en utilisant « mencoder » –

+0

Je sais qu'il ya une façon de le faire » à la volée ': en activant le mode interactif, vous pouvez appeler la méthode pylab.draw() qui va redessiner l'intrigue à chaque fois. J'ai un moyen de modifier les données, etc.déjà (je change juste la couleur d'un de mes cercles) Je veux juste savoir, comment puis-je montrer les cercles et les lignes dans un tracé en utilisant pylab.plot(), je ne connais pas la syntaxe pour pylab.plot() qui vous permet de dessiner un tracé standard avec quelques formes, et aucun graphe ou quoi que ce soit. –

1

Il semble que Mark a la réponse que vous recherchez, mais si vous décidez d'aller avec l'approche de whatnick et de construire une animation à partir PNGs individuels, voici le code pour mettre en œuvre la suggestion de Amit d'utiliser mencoder (de http://en.wikibooks.org/wiki/Mplayer):

mencoder mf://*.png -mf w=400:h=400 -ovc lavc -lavcopts vcodec=xvid -of avi -o output.avi 
Questions connexes