Edit vector interactively using PlutoUI

This is a simplified example of what I need to do:

x = rand(10)
@bind idx Slider(1:length(x))
@bind del Button("-")

I want to trigger deleteat!(x, idx) only when button is pressed and then to refresh the plot and the slider. How to prevent the deleteat! being triggered automatically and only when the button is pressed and how to refresh x later on?

Thanks, Adam

I think we could start chipping away at this by using confirm in PlutoUI. For example, something like:


using Plots, PlutoUI

x = Vector{Union{Float64, Missing}}(rand(5))

@bind idx confirm(Slider(eachindex(x); show_value=true))

    replace!(x, x[idx] => missing)

    xlims!(0, length(x) + 1)
    ylims!(0, 1)

I just made a few tweaks to make it a bit easier for me to see which bars are being removed, but you don’t have to do this. The main difference is that the plot will only update after the confirm button is clicked

As you can see though, this is automatically removing the first bar before we do anything because the default value from the slider is the first index of x. To get around this, I think we could put the deletion behind a CheckBox and then update everything all together with PlutoUI.combine:


@bind options confirm(
    PlutoUI.combine() do Child
        Delete idx: $(Child("idx", Slider(eachindex(y))))

        Update graph: $(Child("update", CheckBox()))

    options.update && replace!(y, y[options.idx] => missing)

    xlims!(0, length(y) + 1)
    ylims!(0, 1)

I like this approach because it creates a named tuple that we can use to refer to each widget. Interestingly though, trying to add show_value to Slider here seems to break things. I’m not sure if this is intended or a known issue, but maybe the Pluto folks would have some more info about this?


Thanks! The issue is that in your solution the length of x is constant and mine should decrease after each removal. Nevertheless, that somewhat does the trick and will suffice until I find a better solution :slight_smile: