Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing an iterator in Julia for an animation with PyPlot

Tags:

I am just trying to reproduce this simple example of an animation in Matplotlib but using PyPlot in Julia. I am having difficulties with the definition of the iterator simData() that is passed to the function funcAnimation , because it seems that PyPlot doesn't recognize the iterator that I defined in Julia (via a Task) as such.

Here is my approach to define the same function 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 

As you can check, this kind of iterator yields in theory the same values than the python simData() generator of the example (try for example collect(simData()). However, I got this error when I try to do the animation

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 

As I mentioned, I think the problem is that the Julia iterator is not recognized as such by Python. Do you have any idea about how to fix that?

PS: Here is a Jupyter notebook with the full code that I used to do the animation.

like image 490
dapias Avatar asked Feb 01 '16 23:02

dapias


1 Answers

In your code, you invoke FuncAnimation() this way:

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

In the original code, simData() was a generator, but in your code it isn't, it returns a generator, so I'd expect your code to invoke it this way:

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

Let's finish the problem -- since we can't get Python to recognize the return value of simData() as an iterator, we'll ignore that feature and have simPoints() call simData() to launch the task and then return a function for Python to animate:

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]() 

This works for one pass of the bouncing ball across the graph and stops when it hits the right edge (unlike the original Python which repeats).

like image 82
cdlane Avatar answered Sep 23 '22 21:09

cdlane