You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Makie动画中实现滑块位置随动画同步移动?

解决Topoplot动画中滑块位置不随时间更新的问题

我在制作Topoplot的GIF动画时,动画内容能正常更新,但滑块的位置始终停留在初始位置,不会随时间戳变化。

滑块位置未变化

我的代码如下:

xs = range(-0.3, length=size(dat_e, 2), step=1 ./ 128) 
sg = SliderGrid(f[2, 1],
    (label="time", range=xs, format = "{:.3f} ms", startvalue = 0),
)
time = sg.sliders[1].value
str = lift(t -> "[$(round(t, digits = 3)) ms]", time)
topo_slice = lift((t, data) -> mean(data[1:30, indexin(t, xs), :], dims=2)[:,1], time, dat_e)
topo_axis = Axis(f[1, 1], aspect = DataAspect(), title = "Interactive topoplot")
topo = eeg_topoplot!(topo_axis, topo_slice, # averaging all trial of 30 participants on Xth msec
    raw.ch_names[1:30]; 
    positions=pos, # produced  automatically from ch_names
    #interpolation=DelaunayMesh(),
    enlarge=1,
    extrapolation=GeomExtrapolation(enlarge=1.0, geometry=Circle),
    label_text=true) # aspect ratio, correlation of height and width

text!(topo_axis, 1, 1, text = str,  align = (:center, :center))
xlims!(-0.2, 1.2)
ylims!(-0.2, 1.2)
hidedecorations!(topo_axis)
hidespines!(topo_axis) 

framerate = 1
timestamps = [-0.3, 0.0828125, 0.1609375, 0.2390625]

record(f, "animations/time_animation.gif", timestamps;
        framerate = framerate) do z
    sg.sliders[1].value[] = z
    time[] = z

问题分析

  1. 你同时修改了sg.sliders[1].value和time,但time本身就是滑块value的引用,重复操作会导致更新逻辑冲突。
  2. 在Makie的录制流程中,仅修改observable的值不足以强制UI组件同步刷新,需要显式触发更新通知。

修复方案

修改录制循环部分的代码,移除重复操作并添加UI更新触发逻辑:

record(f, "animations/time_animation.gif", timestamps; framerate = framerate) do z
    sg.sliders[1].value[] = z
    notify(sg.sliders[1].value)  # 强制通知UI更新滑块位置
    sleep(0.05)  # 短暂延迟确保渲染完成
end

完整修改后的代码

xs = range(-0.3, length=size(dat_e, 2), step=1 ./ 128) 
sg = SliderGrid(f[2, 1],
    (label="time", range=xs, format = "{:.3f} ms", startvalue = 0),
)
time = sg.sliders[1].value
str = lift(t -> "[$(round(t, digits = 3)) ms]", time)
topo_slice = lift((t, data) -> mean(data[1:30, indexin(t, xs), :], dims=2)[:,1], time, dat_e)
topo_axis = Axis(f[1, 1], aspect = DataAspect(), title = "Interactive topoplot")
topo = eeg_topoplot!(topo_axis, topo_slice, # averaging all trial of 30 participants on Xth msec
    raw.ch_names[1:30]; 
    positions=pos, # produced  automatically from ch_names
    #interpolation=DelaunayMesh(),
    enlarge=1,
    extrapolation=GeomExtrapolation(enlarge=1.0, geometry=Circle),
    label_text=true) # aspect ratio, correlation of height and width

text!(topo_axis, 1, 1, text = str,  align = (:center, :center))
xlims!(-0.2, 1.2)
ylims!(-0.2, 1.2)
hidedecorations!(topo_axis)
hidespines!(topo_axis) 

framerate = 1
timestamps = [-0.3, 0.0828125, 0.1609375, 0.2390625]

record(f, "animations/time_animation.gif", timestamps;
        framerate = framerate) do z
    sg.sliders[1].value[] = z
    notify(sg.sliders[1].value)
    sleep(0.05)
end

关键说明

  • notify()会触发所有依赖该observable的UI元素更新,确保滑块位置同步变化。
  • 移除time[] = z,因为time是滑块value的直接引用,修改滑块value已同步更新time的值。
  • 短暂的sleep()是为了给Makie足够时间完成滑块UI的渲染,避免录制帧时滑块位置未更新。

内容的提问来源于stack exchange,提问作者Vladimir Mikheev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 18:15:27