2012-11-18 11 views
14

Chciałbym animować wykres, który rośnie z upływem czasu.Animowanie wzrostu sieci za pomocą NetworkX i Matplotlib

To, co mam tak daleko:

fig = plt.figure() 
ims = [] 
graph = nx.Graph() 
for i in range(50): 
    // Code to modify Graph 
    nx.draw(graph, pos=nx.get_node_attributes(graph,'Position')) 
    im = plt.draw() 
    self.ims.append([im]) 
ani = animation.ArtistAnimation(fig, ims, interval=50, blit=True,repeat_delay=1000) 
ani.save('dynamic_images.mp4') 
plt.show() 

jednak, pojawia się następujący komunikat o błędzie:

File "main.py", line 204, in <module> 
    repeat_delay=1000) 
    File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 356, in __init__ 
    TimedAnimation.__init__(self, fig, *args, **kwargs) 
    File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 304, in __init__ 
    Animation.__init__(self, fig, event_source=event_source, *args, **kwargs) 
    File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 53, in __init__ 
    self._init_draw() 
    File "/usr/lib/pymodules/python2.7/matplotlib/animation.py", line 363, in _init_draw 
    artist.set_visible(False) 
AttributeError: 'NoneType' object has no attribute 'set_visible' 
[email protected]:~/Desktop/CS8903-SpecialProblem/Code/ 

Co chcę jest animacja, gdzie można zobaczyć wykres rośnie. Mogę zapisać wykres na każdym etapie i może być w stanie stworzyć animację poza matplotlib, ale czy jest jakiś sposób na to, aby działał w ten sposób?

+0

Jaki jest Twój backend? Napotkałem pewne problemy z animacją z niektórymi backendami. Czy możesz uruchomić matplotlib [basic_example.py] (http://matplotlib.org/examples/animation/basic_example.html)? – tiago

+0

Tak, to działa idealnie dla mnie. Co do zaplecza, to właśnie na ubuntu, python 2.7, numpy, scipy, networkx i matplotlib ... wszystko zainstalowane w ciągu ostatnich kilku dni, więc są one najnowszą wersją ... Im po prostu student, i Wypróbuję kilka expereriments, To byłoby naprawdę pomocne animować te wykresy, więc mogę zobaczyć, jak rosną! – Nicomoto

+0

Nie jestem zaznajomiony z networkx. Być może problem polega na tym, że "ArtistAnimation" oczekuje artysty matplotlib, a nie obiektu nx? – tiago

Odpowiedz

9

Po sprawdzeniu ten kod nie był tak istotny dla tego problemu, jak myślałem. Jednak udało mi się użyć this SO answer i this SO answer, aby zebrać odpowiedź dla Ciebie. Oto kod, który utworzy wykres, doda 50 losowych węzłów i 50 losowych krawędzi do niego i wyświetli obraz wykresu po dodaniu każdego węzła i krawędzi. Kilka z kluczowych zmian od kodu:

  1. Kod ten jest oparty na wykorzystaniu pylab.ion() (patrz here aby uzyskać więcej informacji).
  2. Twój kod próbuje użyć jednej cyfry i zmienić obraz w niej. Ten kod tworzy nową liczbę dla każdej ramki.
  3. Ten kod nie jest zapisywany w .mp4. Jeśli naprawdę musisz to zrobić, sugerowałbym zapisanie liczb do pliku .png podczas renderowania i konwertowanie do MP4 po fakcie.
  4. Należy zauważyć, że ten kod używa matplotlib.pyplot.pause() zamiast time.sleep(). Liczby nie będą wyświetlane, jeśli użyjesz time.sleep().

Powodzenia!

import random 
import pylab 
from matplotlib.pyplot import pause 
import networkx as nx 
pylab.ion() 

graph = nx.Graph() 
node_number = 0 
graph.add_node(node_number, Position=(random.randrange(0, 100), random.randrange(0, 100))) 

def get_fig(): 
    global node_number 
    node_number += 1 
    graph.add_node(node_number, Position=(random.randrange(0, 100), random.randrange(0, 100))) 
    graph.add_edge(node_number, random.choice(graph.nodes())) 
    fig = pylab.figure() 
    nx.draw(graph, pos=nx.get_node_attributes(graph,'Position')) 
    return fig 

num_plots = 50; 
pylab.show() 

for i in range(num_plots): 

    fig = get_fig() 
    fig.canvas.draw() 
    pylab.draw() 
    pause(2) 
    pylab.close(fig) 
+0

Bardzo przepraszam za opóźnienie, tak czy inaczej, twoja sugestia jest tym, co skłoniło mnie do myślenia, oto co zrobiłem najpierw, wykreśliłem wykres i zapisałem poszczególne png, a następnie zszusowałem je razem na zewnątrz ... Wykonałem również implementację z jonem, jedynym problemem jest to, że nie mogę zapisać tych plików jako plików GIF, ale jest to raczej fajne, ponieważ widać zmiany w czasie wykonywania. – Nicomoto

+0

Dzięki! Chciałem wypróbować alternatywne rozwiązanie z użyciem matplotlib.animation.FuncAnimation (więcej informacji na stronie http://matplotlib.org/api/animation_api.html), ale nie miałem czasu. – brentlance

12

Udoskonalona wersja bretlance. Mam nadzieję, że będzie to pomocne. Pokaże animacje ale nie zdjęcie po zdjęciu.

Nadal nie wiem jak właściciel pytanie Animate drawing networkx edges skorzystał z matplotlib w animacji

#!/usr/bin/env python 
import random 
import pylab 
from matplotlib.pyplot import pause 
import networkx as nx 
pylab.ion() 

graph = nx.Graph() 
node_number = 0 
graph.add_node(node_number, Position=(random.randrange(0, 100), random.randrange(0, 100))) 

def get_fig(): 
    global node_number 
    node_number += 1 
    graph.add_node(node_number, Position=(random.randrange(0, 100), random.randrange(0, 100))) 
    graph.add_edge(node_number, random.choice(graph.nodes())) 
    nx.draw(graph, pos=nx.get_node_attributes(graph,'Position')) 

num_plots = 50; 
pylab.show() 

for i in range(num_plots): 

    get_fig() 
    pylab.draw() 
    pause(2) 
+0

dokładnie to, czego szukałem. Ładne przejście między jednym rysunkiem do drugiego. Zmniejszenie pauzy zapewnia płynną animację. Dzięki. :) – mythicalcoder

Powiązane problemy