When using a Slider that changes a variable in a function, sometimes the amplitude can change quite a lot. In some cases, it makes sense to resize the axes to see what’s going on in a plot. This can easily be done in GLMakie by using autolimits!() after updating the variable. However, if the number of decimal places of the axis tick labels changes, this causes the Axis itself to resize, making the plot jitter. This is undesirable. I am working around this by setting yticklabelspace (for the y axis) large enough that this won’t happen.
I’m wondering if this is the canonical way to solve this or if there is a better way?
Example:
using GLMakie
x = 0:0.1:6π
A = Observable(1.0)
y(x, A) = A * sin.(x)
oy = Observable(y(x, to_value(A)))
fig = Figure()
display(fig)
ax = Axis(fig[1, 1], ylabel = "y", xlabel = "x",
yticklabelspace = 20.0
)
lines!(x, oy)
sg = SliderGrid(fig[2, 1],
(label = "Amplitude", range = 0:0.01:10, format = "{:.1f}", startvalue=1)
)
on(sg.sliders[1].value) do val
A[] = val
oy[] = y(x, to_value(A))
autolimits!(ax)
end
Without yticklabelspace
With yticklabelspace (now tick labels cover the axis label, but that can be fixed)
tight_ticklabels!(ax) # set good fixed limits to start with
timer = SomeTimer(latency = 300ms_or_so)
on(timer_fires) do
tight_ticklabels!(ax)
end
on(slider.value) do value
update_plot_using(value)
start_or_reset_some_timer!(timer)
end
Thanks for the suggestion. This works alright, but getting the timer right is tricky. It would be nice if it would update only when the slider stopped. The callback function only runs once while I’m moving the slider and I’m not sure how to get the timer to fire with each value change of the slider. I’m not sure if I’m implementing this right, but this is what I’m trying:
x = 0:0.1:6π
A = Observable(1.0)
y(x, A) = A * sin.(x)
oy = Observable(y(x, to_value(A)))
fig = Figure()
display(fig)
ax = Axis(fig[1, 1], ylabel = "y", xlabel = "x")
lines!(x, oy)
tight_ticklabel_spacing!(ax)
sg = SliderGrid(fig[2, 1],
(label = "Amplitude", range = 0:0.01:10, format = "{:.1f}", startvalue=1))
function cb(timer)
wait(timer)
tight_ticklabel_spacing!(ax)
end
on(sg.sliders[1].value) do val
A[] = val
oy[] = y(x, to_value(A))
autolimits!(ax)
timer = Timer(cb, 0.3, interval=0.3)
end