如何使用 Makie 的流图为时变函数制作动画?
How can you animate a time-varying function using Makie's streamplot?
我一直在尝试绘制一个简单的函数:
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 的二维流图功能。
虽然我可以通过创建匿名函数 f = x -> v(x, 5e0)
(例如)并绘制 f
来单独绘制每个时间步长,但当我尝试将其包装在 Observable 中时(使用 Node(f)
), 然后我不能再更新 Observable 指向另一个函数,所以我的记录循环失败。
我试过强制节点的类型更抽象 (Node{Function}
)。不幸的是,这个抽象类型似乎在 Makie 内部的某个地方丢失了,因此丢失了。
有什么方法可以包装我的类型,以免 运行 陷入类型冲突,但仍然是一个函数?
原来有这个可爱的 Base 方法 Fix2(function, argument)
,它基本上解决了我的问题(因为它 returns 是一个包装类型)。
考虑这个示例函数:
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
我一直在尝试绘制一个简单的函数:
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 的二维流图功能。
虽然我可以通过创建匿名函数 f = x -> v(x, 5e0)
(例如)并绘制 f
来单独绘制每个时间步长,但当我尝试将其包装在 Observable 中时(使用 Node(f)
), 然后我不能再更新 Observable 指向另一个函数,所以我的记录循环失败。
我试过强制节点的类型更抽象 (Node{Function}
)。不幸的是,这个抽象类型似乎在 Makie 内部的某个地方丢失了,因此丢失了。
有什么方法可以包装我的类型,以免 运行 陷入类型冲突,但仍然是一个函数?
原来有这个可爱的 Base 方法 Fix2(function, argument)
,它基本上解决了我的问题(因为它 returns 是一个包装类型)。
考虑这个示例函数:
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