# Makie - How to clear ax whenever slider value change?

**URL:** <https://discourse.julialang.org/t/makie-how-to-clear-ax-whenever-slider-value-change/103274>\
**Category:** Visualization\
**Tags:** makie\
**Created:** [August 28, 2023, 6:01am UTC](https://discourse.julialang.org/t/makie-how-to-clear-ax-whenever-slider-value-change/103274 "2023-08-28T06:01:13Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ashu](https://avatars.discourse-cdn.com/v4/letter/a/4bbf92/32.png) [@Ashu](https://discourse.julialang.org/u/Ashu)\
**Post date:** [August 28, 2023, 6:01am UTC](https://discourse.julialang.org/t/makie-how-to-clear-ax-whenever-slider-value-change/103274/1 "2023-08-28T06:01:13Z")

</div>

Hello,

How can I clear the ‘ax’ whenever the slider value changes? I don’t want multiple lines at the same time on the scene. The code is

```julia
using GLMakie

# Parameters
local m = 0.0
local c = 0.0

# # Create the plot
fig = Figure(resolution = (800, 600))
ax = Axis(fig[1,1])

# Simulation loop
function test()
    
    x = 0:0.01:10
    f(x) = m * x + c
    lines!(ax, x, f.(x))

end

# Create a slider for m
m_slider = Slider(fig[2, 1], value = m, range = 0.0:0.5:10.0)

# Create a slider for c
c_slider = Slider(fig[3, 1], value = c, range = 0.0:1.0:10.0)

# Add a callback for the m slider
on(m_slider.value) do value
    global m = value # Update m value
    test()
end

# Add a callback for the c slider
on(c_slider.value) do value
    global c = value # Update c value
    test()
end

# Display the figure
display(fig)

```

Could anyone please help?

---

<div class="post-metadata">

**Author:** ![fatteneder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fatteneder/32/33991_2.png) [@fatteneder](https://discourse.julialang.org/u/fatteneder)\
**Post date:** [August 28, 2023, 6:59am UTC](https://discourse.julialang.org/t/makie-how-to-clear-ax-whenever-slider-value-change/103274/2 "2023-08-28T06:59:51Z")

</div>

Using globals to make Makie’s plots interactive is not optimal. Instead you should look into how Observables work. See here for more infos: [Observables & Interaction · Makie](https://docs.makie.org/stable/documentation/nodes/)

Here is a reworked version of your example

```julia
using GLMakie

# Parameters
m = Observable(0.0)
c = Observable(0.0)
x = 0:0.01:10
y = Observable(Float64[])
f(x,m,c) = m*x+c

# Create a figure with an axis
fig = Figure(resolution = (800, 600))
ax = Axis(fig[1,1])

# Create a slider for m
m_slider = Slider(fig[2, 1], value = m[], range = 0.0:0.5:10.0)

# Create a slider for c
c_slider = Slider(fig[3, 1], value = c[], range = 0.0:1.0:10.0)

y = lift(m_slider.value, c_slider.value) do m, c
   # lift is similar to on (or onany), only that its return value will be wrapped into an Observable
   return f.(x,m,c)
end

on(y) do _
    # whenever y changes we update the axis limits
    reset_limits!(ax)
end

lines!(ax, x, y)

# Display the figure
display(fig)

```

---

<div class="post-metadata">

**Author:** ![Ashu](https://avatars.discourse-cdn.com/v4/letter/a/4bbf92/32.png) [@Ashu](https://discourse.julialang.org/u/Ashu)\
**Post date:** [August 28, 2023, 9:01am UTC](https://discourse.julialang.org/t/makie-how-to-clear-ax-whenever-slider-value-change/103274/3 "2023-08-28T09:01:22Z")

</div>

Thank you @fatteneder. Based on the code you provided I write another code which uses some general function. But, I am not getting anything on the figure. Could you please check and let me know what is the issue now? The code is-

```julia
using GLMakie

k = Observable(0.0)
c = Observable(0.0)
position = 0.0
velocity = 0.0
time_step = 0.1
m = 1
num_steps = 100
positions = [position]
times = [0.0]

# Simulation function
function simulate_step(position, velocity, k, c)
    acceleration = ((-k) * position - c * velocity) / m
    new_velocity = velocity + acceleration * time_step
    new_position = position + new_velocity * time_step
    return new_position, new_velocity
end

# Create the plot
fig = Figure(resolution = (800, 600))
ax = Axis(fig[1,1])

# Create a slider for stiffness
stiffness_slider = Slider(fig[2, 1], value = k[], range = 0.1:0.1:20.0, startvalue = 0)

# Create a slider for damping
damping_slider = Slider(fig[3, 1], value = c[], range = 0.1:0.1:5.0, startvalue = 0)

on(stiffness_slider.value) do value
    k[] = value   
end

on(k) do k
    for i in 1:num_steps
        position, velocity = simulate_step(position, velocity, k, c)
        push!(positions, position)
        push!(times, i*time_step)
    end
    fig(lines!(times, positions))
end

on(damping_slider.value) do value
    c[] = value
end

on(c) do c
    for i in 1:num_steps
        position, velocity = simulate_step(position, velocity, k, c)
        push!(positions, position)
        push!(times, i*time_step)
    end
    fig(lines!(times, positions))
end

display(fig)

```

---

<div class="post-metadata">

**Author:** ![fatteneder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fatteneder/32/33991_2.png) [@fatteneder](https://discourse.julialang.org/u/fatteneder)\
**Post date:** [August 28, 2023, 10:31am UTC](https://discourse.julialang.org/t/makie-how-to-clear-ax-whenever-slider-value-change/103274/4 "2023-08-28T10:31:22Z")

</div>

Basically, you want to use the exact same scheme as in my first post, but this needs some getting used to. Below is a minimal recipe to approach the problem.

1. Firstly, always make a plot without interactivity first to make sure everything else besides the interactive part is already working. For your example this could look something like

```julia
using GLMakie
GLMakie.activate!()

position = 0.0
velocity = 0.1
time_step = 0.1
m = 1
num_steps = 100

# these are supposed to be varied later on
k = 0.0
c = 0.0
positions = [position]
times = [0.0]

# Simulation function
function simulate_step(position, velocity, k, c)
    acceleration = ((-k) * position - c * velocity) / m
    new_velocity = velocity + acceleration * time_step
    new_position = position + new_velocity * time_step
    return new_position, new_velocity
end

# Create the plot
fig = Figure(resolution = (800, 600))
ax = Axis(fig[1,1])

for i in 1:num_steps
    p, v = simulate_step(position, velocity, k, c)
    push!(positions, p)
    push!(times, i*time_step)
end

lines!(times, positions)

display(fig)

```

1. Then you step through your script and insert the necessary widgets and listeners (`on, onany`) calls.

```julia
using GLMakie
GLMakie.activate!()

position = 0.0
velocity = 0.1
time_step = 0.1
m = 1
num_steps = 100
positions = [position]
times = [0.0]

k = Observable(0.0)
c = Observable(0.0)
positions = Observable([position])
times = Observable([0.0])

# Simulation function
function simulate_step(position, velocity, k, c)
    acceleration = ((-k) * position - c * velocity) / m
    new_velocity = velocity + acceleration * time_step
    new_position = position + new_velocity * time_step
    return new_position, new_velocity
end

# Create the plot
fig = Figure(resolution = (800, 600))
ax = Axis(fig[1,1])

# Create a slider for stiffness
stiffness_slider = Slider(fig[2, 1], value = k[], range = 0.1:0.1:20.0, startvalue = 0)
# Create a slider for damping
damping_slider = Slider(fig[3, 1], value = c[], range = 0.1:0.1:5.0, startvalue = 0)

on(stiffness_slider.value) do value
    k[] = value
end
on(damping_slider.value) do value
    c[] = value
end

onany(k, c) do k, c
    # need to reset storage for next plot update
    # use .val on Observable objects to avoid triggering premature plotting updates
    # this is needed to avoid length-mismatch errors and similar problems
    resize!(positions.val, 1)
    resize!(times.val, 1)
    positions.val[1] = position
    times.val[1] = 0.0
    for i in 1:num_steps
        p, v = simulate_step(position, velocity, k, c)
        push!(positions.val, p)
        push!(times.val, i*time_step)
    end
    # when done updating data notify everyone listening to our data
    notify(positions)
end
# trigger the pipeline once so that we have something to display on first plot
notify(stiffness_slider.value)

on(positions) do _
    reset_limits!(ax)
end

lines!(times, positions)

display(fig)

```

1. [Optional] Optimize the pipeline if needed. In your case one could think about whether it is a good idea to empty the vectors `positions, times` on every plot update. A more performant version would use a preallocated vector of length `num_steps` for both `positions, times`.
