2016-02-01 11 views
19

Próbuję odtworzyć tę prostą example animacji w Matplotlib, ale używając PyPlot w Julii. Mam trudności z definicją iteratora simData(), który jest przekazywany do funkcji funcAnimation, ponieważ wydaje się, że PyPlot nie rozpoznaje iteratora, który zdefiniowałem w Julia (przez Task) jako taki.Implementacja iteratora w Julii do animacji z PyPlot

Oto moje podejście do definiowania samą funkcję simData():

function simData() 

    t_max = 10.0 
    dt = 0.05 
    x = 0.0 
    t = 0.0 

    function it() 
     while t < t_max 
      x = sin(pi*t) 
      t = t+dt 
      produce(x,t) 
     end 
    end 
    Task(it) 
end 

Jak można sprawdzić, tego rodzaju rentowności iterator w teorii te same wartości niż generatora przykładzie pyton simData() (spróbuj na przykład collect(simData()) . jednak mam ten błąd, gdy próbuję zrobić animację

LoadError: PyError (:PyObject_Call) <type 'exceptions.TypeError'> 
TypeError('PyCall.jlwrap object is not an iterator',) 
    File "/usr/local/lib/python2.7/dist-packages/matplotlib/animation.py", line 1067, in __init__ 
    TimedAnimation.__init__(self, fig, **kwargs) 
    File "/usr/local/lib/python2.7/dist-packages/matplotlib/animation.py", line 913, in __init__ 
    *args, **kwargs) 
    File "/usr/local/lib/python2.7/dist-packages/matplotlib/animation.py", line 591, in __init__ 
    self._init_draw() 
    File "/usr/local/lib/python2.7/dist-packages/matplotlib/animation.py", line 1092, in _init_draw 
    self._draw_frame(next(self.new_frame_seq())) 

while loading In[5], in expression starting on line 42 

in pyerr_check at /home/diegotap/.julia/v0.4/PyCall/src/exception.jl:56 
[inlined code] from /home/diegotap/.julia/v0.4/PyCall/src/exception.jl:81 
in pycall at /home/diegotap/.julia/v0.4/PyCall/src/PyCall.jl:402 
in call at /home/diegotap/.julia/v0.4/PyCall/src/PyCall.jl:429 

jak już wspomniałem, że problemem jest to, że iterator Julia nie jest rozpoznawane jako takie przez Pythona. Czy masz jakiś pomysł, ab jak to naprawić?

PS: Here to notebook Jupyter z pełnym kodem, z którego korzystałem podczas animacji.

Odpowiedz

7

W kodzie wywołać FuncAnimation ten sposób:

ani = anim.FuncAnimation(fig, simPoints, simData, blit = false, interval=10, repeat= true) 

w oryginalnym kodzie simdata był generator, ale w kodzie nie jest, zwraca generator, więc będę oczekiwać Twój kod powołać się to w ten sposób:

ani = anim.FuncAnimation(fig, simPoints, simData(), blit = false, interval=10, repeat= true) 

skończmy ten problem - ponieważ nie możemy dostać Pythona rozpoznać wartość zwracaną simdata() jako interator będziemy ignorować tę funkcję i mieć SimPoints() wywołaj simData(), aby uruchomić zadanie, a następnie zwróć funkcję do animacji w Pythonie:

using PyCall 
using PyPlot 
pygui(true) 

@pyimport matplotlib.animation as animation 

function simData() 
    t_max = 10.0 
    dt = 0.05 
    x = 0.0 
    t = -dt 

    function it() 
     while t < t_max 
      x = sin(pi * t) 
      t = t + dt 
      produce(x, t) 
     end 
    end 

    Task(it) 
end 

function simPoints() 
    task = simData() 

    function points(frame_number) 
     x, t = consume(task) 
     line[:set_data](t, x) 
     return(line, "") 
    end 

    points 
end 

figure = plt[:figure]() 
axis = figure[:add_subplot](111) 
line = axis[:plot]([], [], "bo", ms = 10)[1] 
axis[:set_ylim](-1, 1) 
axis[:set_xlim](0, 10) 

ani = animation.FuncAnimation(figure, simPoints(), blit=false, interval=10, frames=200, repeat=false) 

plt[:show]() 

ten działa na jednym przejściu odbijanie kulki na wykresie i zatrzymuje się, gdy uderza w prawo (w przeciwieństwie do krawędzi pierwotnej Pythonie która powtarza).