簡體   English   中英

使用 PyPlot 在 Julia 中為動畫實現迭代器

[英]Implementing an iterator in Julia for an animation with PyPlot

我只是想在 Matplotlib 中重現這個簡單的動畫示例,但在 Julia 中使用 PyPlot。 我在定義傳遞給函數funcAnimation的迭代器simData()時遇到了困難,因為 PyPlot 似乎無法識別我在 Julia 中定義的迭代器(通過Task )。

這是我定義相同函數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

如您simData() ,這種迭代器在理論上產生與示例的 python simData()生成器相同的值(嘗試例如collect(simData()) 。但是,當我嘗試執行動畫時出現此錯誤

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

正如我所提到的,我認為問題在於 Python 無法識別 Julia 迭代器。 你知道如何解決這個問題嗎?

PS: 是一個 Jupyter notebook,里面有我用來做動畫的完整代碼。

在您的代碼中,您可以通過以下方式調用FuncAnimation()

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

在原始代碼中, simData()是一個生成器,但在您的代碼中它不是,它返回一個生成器,所以我希望您的代碼以這種方式調用它:

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

讓我們解決這個問題——因為我們無法讓 Python 將simData()的返回值識別為迭代器,我們將忽略該功能並讓simPoints()調用simData()來啟動任務,然后返回一個函數為 Python 制作動畫:

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

這適用於彈跳球穿過圖形的一次傳球,並在它擊中右邊緣時停止(與重復的原始 Python 不同)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM