3

我一直在尝试绘制一个简单的函数:

v(x, y) = (y*t, 2*x*t)

(实际实现v(x::Point2{T}, t) where T = Point2{T}(one(T) * x[2] * t, 4 * x[1]):)

使用 Makie 的 2D 流图功能。

f = x -> v(x, 5e0)虽然我可以通过创建一个匿名函数(例如)和plot 来单独绘制每个时间步f,但当我尝试将它包装在 Observable 中(使用Node(f))时,我不能再更新该 Observable 以指向另一个函数,所以我的记录循环失败。

我试过强制节点的类型更抽象(Node{Function})。不幸的是,这种抽象类型似乎在 Makie 内部的某个地方丢失了,因此丢失了。

有什么办法可以包装我的类型,以免遇到类型冲突,但仍然是一个函数?

4

1 回答 1

6

所以事实证明有这个可爱的 Base 方法Fix2(function, argument),它基本上解决了我的问题(因为它返回一个包装类型)。

考虑这个示例函数:

v(x::Point2{T}, t) where T = Point2{T}(one(T) * x[2] * t, 4 * x[1])

可以通过以下方式创建时间设置为 1.0 的可调用函数:

fixedfunc = Base.Fix2(v, 1.0)

然后可以将其加载到 Observable 中,并更新为具有新的时间值而不会出现问题。

这是最终代码,供参考:

v(x::Point2{T}, t) where T = Point2{T}(one(T) * x[2] * t, 4 * x[1])
sf = Node(Base.Fix2(v, 0e0))

title_str = Node("t = 0.00")

sp = streamplot(
        sf,
        -2..2, -2..2;
        linewidth = 2,
        padding = (0, 0),
        arrow_size = 0.09,
        colormap =:magma
    )

sc = title(sp, title_str)

record(sc, "test.mp4", LinRange(0, 20, 5*30)) do i
  sf[] = Base.Fix2(v, i)
  title_str[] = "t = $(round(i; sigdigits = 2))"
end

视频

于 2019-09-15T04:25:54.283 回答