# Interactive FFT with an intervalslider in Makie

**URL:** <https://discourse.julialang.org/t/interactive-fft-with-an-intervalslider-in-makie/63112>\
**Category:** Visualization\
**Tags:** makie\
**Created:** [June 17, 2021, 8:09pm UTC](https://discourse.julialang.org/t/interactive-fft-with-an-intervalslider-in-makie/63112 "2021-06-17T20:09:23Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Flausi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/flausi/32/19847_2.png) [@Flausi](https://discourse.julialang.org/u/Flausi)\
**Post date:** [June 17, 2021, 8:09pm UTC](https://discourse.julialang.org/t/interactive-fft-with-an-intervalslider-in-makie/63112/1 "2021-06-17T20:09:24Z")

</div>

Hello, I have taken a relatively large amount of readings over time and would now like to look at them in detail. For this purpose I use an interval slider in Makie with which I can zoom into my data. This works already very well.  
In the next step I want to run a fast fourier transformation dynamically over the selected area. This should be adjusted with the slider position. I’ve played around a bit, but haven’t made it to work yet. Maybe someone of you has an idea.

```julia
intSh1 = IntervalSlider(fig[2, 1], range = collect(1:1:length(test_time)), startvalues = (1, length(test_time)), linewidth = 20)

Label(fig[2, 1], @lift(string(test_time[$(intSh1.interval)[1]]) * " sec bis " * string(test_time[$(intSh1.interval)[2]]) * " sec"), tellwidth = false)

vlines!(ax0, @lift(test_time[$(intSh1.interval)[1]]), ymin = -2.0, ymax = 2.0, color = :red, linewidth = 2)
vlines!(ax0, @lift(test_time[$(intSh1.interval)[2]]), ymin = -2.0, ymax = 2.0, color = :red, linewidth = 2)

F = rfft(volt) |> fftshift
freqs = rfftfreq(length(test_time), 1/(steptime*1e-3)) |> fftshift

new_fft = lift(intSh1.interval) do val
    F = rfft(volt[val[1]:val[2]]) |> fftshift
    freqs = rfftfreq(length(test_time[val[1]:val[2]]), 1/(steptime*1e-3)) |> fftshift
end

new_lims = lift(intSh1.interval) do val
    limits!(ax1, FRect(test_time[val[1]], -0.75, test_time[val[2]] - test_time[val[1]], 1.5))
end

lines!(ax0, test_time, volt, linewidth = 0.5, color = :blue)
lines!(ax1, test_time, volt, linewidth = 1, color = :blue)
lines!(ax2, freqs, abs.(F), linewidth = 1, color = :blue)

display(fig)

```

 ![2021-06-17 18_28_57-Window](https://global.discourse-cdn.com/julialang/original/3X/3/9/39ed8541d6ba01d113a294175e511ab4d26eec99.png)

---

<div class="post-metadata">

**Author:** ![contradict](https://avatars.discourse-cdn.com/v4/letter/c/ac91a4/32.png) [@contradict](https://discourse.julialang.org/u/contradict)\
**Post date:** [June 18, 2021, 3:17am UTC](https://discourse.julialang.org/t/interactive-fft-with-an-intervalslider-in-makie/63112/2 "2021-06-18T03:17:39Z")

</div>

```julia
using FFTW, GLMakie

function interactive(data, timestep)

    N = size(data, 1)

    time = range(0, step=timestep, length=N) |> collect

    fig = Figure(resolution=(2400, 1400))

    ax0 = fig[1,1] = Axis(fig)

    intSh1 = fig[2,1] = IntervalSlider(
            fig,
            range = 1:N,
            startvalues = (1, N),
            linewidth = 20)
    fig[2, 1] = Label(
            fig,
            @lift(string(time[$(intSh1.interval)[1]]) * " sec bis " * string(time[$(intSh1.interval)[2]]) * " sec"),
            tellwidth = false)

    ax1 = fig[3,1] = Axis(fig)
    ax2 = fig[4,1] = Axis(fig)

    vlines!(ax0, @lift(time[$(intSh1.interval)[1]]), ymin = -2.0, ymax = 2.0, color = :red, linewidth = 2)
    vlines!(ax0, @lift(time[$(intSh1.interval)[2]]), ymin = -2.0, ymax = 2.0, color = :red, linewidth = 2)

    # The plotted values need to be observables so they update on change, and they must
    # be synchronized.
    # https://makie.juliaplots.org/stable/interaction/nodes.html#Problems-With-Synchronous-Updates
    new_freqs = Node(rfftfreq(N, 1/timestep)|>fftshift|>collect)
    new_F = lift(intSh1.interval) do val
        new_freqs.val = rfftfreq(val[2]-val[1]+1, 1/timestep) |> fftshift |> collect
        rfft(data[val[1]:val[2]]) |> fftshift .|> abs
    end

    new_lims = lift(intSh1.interval) do val
        limits!(ax1, FRect(time[val[1]], -0.75, time[val[2]] - time[val[1]], 1.5))
    end

    lines!(ax0, time, data, linewidth = 0.5, color = :blue)
    lines!(ax1, time, data, linewidth = 1, color = :blue)
    lines!(ax2, new_freqs, new_F, linewidth = 1, color = :blue)

    display(fig)

end

```

---

<div class="post-metadata">

**Author:** ![Flausi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/flausi/32/19847_2.png) [@Flausi](https://discourse.julialang.org/u/Flausi)\
**Post date:** [June 18, 2021, 9:31am UTC](https://discourse.julialang.org/t/interactive-fft-with-an-intervalslider-in-makie/63112/3 "2021-06-18T09:31:44Z")

</div>

Thank you for the quick reply. Unfortunately I still do not understand the functions of `|>`  
There is a function applied to the argument before it or? What is the advantage in this syntax? If I have understood it correctly are `sum([1:5;])` and `[1:5;] |> sum` the same or?

Thanks and sorry if it’s a very stupid question 😉

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [June 18, 2021, 1:52pm UTC](https://discourse.julialang.org/t/interactive-fft-with-an-intervalslider-in-makie/63112/4 "2021-06-18T13:52:18Z")

</div>

Yes, it’s just a stylistic question. Sometimes a sequence of functions being applied is easier to grasp than reading inside out `func3(func2(func1(x)))`
