# Webpage with reactive plot animation

**URL:** https://discourse.julialang.org/t/webpage-with-reactive-plot-animation/121570
**Category:** General Usage
**Tags:** web, genie
**Created:** [October 22, 2024, 5:13am UTC](https://discourse.julialang.org/t/webpage-with-reactive-plot-animation/121570 "2024-10-22T05:13:29Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [October 22, 2024, 5:13am UTC](https://discourse.julialang.org/t/webpage-with-reactive-plot-animation/121570/1 "2024-10-22T05:13:29Z")

</div>

I’d like to have a webpage with a plot which gets updated automatically every second, and which depends on some user input. Schematically, something like:

```julia
julia> xs = [0]; vx = ReactiveSlider(initial_value=1)
       while true
           push!(xs, xs[end]+vx[])  
           println(x)
           sleep(1)
           plot!(xs) # update plot
       end

```

Or, for a concrete example, “Here is a plot of how much distance the car has traveled so far (x). Adjust the slider value to adjust the speed of the car (vx) in real time”

I was able to get this working [in Pluto](https://discourse.julialang.org/t/playing-with-live-plots-in-pluto/44062). But as far as I know, one can still not easily serve a (dynamic, julia-process-backed) notebook as a webpage that multiple people can access simultaneously, right? What would be my best option for this? Dash? Genie? Dash being stateless makes it sound messy (from my limited experience).

---

<div class="post-metadata">

### Author: ![zweiglimmergneis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zweiglimmergneis/32/7892_2.png) [@zweiglimmergneis](https://discourse.julialang.org/u/zweiglimmergneis)
#### Post date: [October 23, 2024, 10:59am UTC](https://discourse.julialang.org/t/webpage-with-reactive-plot-animation/121570/2 "2024-10-23T10:59:50Z")

</div>

Did you have a look at [Bonito.jl](https://simondanisch.github.io/Bonito.jl/stable/) and [Oxygen.jl](https://oxygenframework.github.io/Oxygen.jl/stable/)?

---

<div class="post-metadata">

### Author: ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)
#### Post date: [October 24, 2024, 5:22am UTC](https://discourse.julialang.org/t/webpage-with-reactive-plot-animation/121570/3 "2024-10-24T05:22:23Z")

</div>

Thank you for the recommendation! I got something working by tweaking a Bonito.jl example:

```julia
using Bonito, Bonito.Observables, Base.Threads

import Bonito.TailwindDashboard as D

function create_svg(sl_nsamples, sl_sample_step, sl_phase, sl_radii, color)
    width, height = 900, 300
    cxs_unscaled = [i*sl_sample_step + sl_phase for i in 1:sl_nsamples]
    cys = sin.(cxs_unscaled) .* height/3 .+ height/2
    cxs = cxs_unscaled .* width/4pi
    rr = sl_radii
    # DOM.div/svg/etc is just a convenience in Bonito for using Hyperscript, but circle isn't wrapped like that yet
    geom = [SVG.circle(cx=cxs[i], cy=cys[i], r=rr, fill=color(i)) for i in 1:sl_nsamples[]]
    return SVG.svg(SVG.g(geom...);
        width=width, height=height
    )
end

obs_phase = Observable(1.0)

app = App() do session
    colors = ["black", "gray", "silver", "maroon", "red", "olive", "yellow", "green", "lime", "teal", "aqua", "navy", "blue", "purple", "fuchsia"]
    color(i) = colors[i%length(colors)+1]
    sl_nsamples = D.Slider("nsamples", 1:200, value=100)
    sl_sample_step = D.Slider("sample step", 0.01:0.01:1.0, value=0.1)
    sl_phase = D.Slider("phase", 0.0:0.1:6.0, value=0.0)
    sl_radii = D.Slider("radii", 0.1:0.1:60, value=10.0)
    svg = map(create_svg, sl_nsamples.value, sl_sample_step.value, obs_phase, sl_radii.value, color)
    return DOM.div(D.FlexRow(D.FlexCol(sl_nsamples, sl_sample_step, obs_phase, sl_radii), svg))
end

@spawn for v in -10:0.01:10
    obs_phase[] = v
    sleep(0.01)
end

app

```

It’s quite straight-forward and it looks cool, props to @sdanisch !

Not quite sure how to make that logic work out per-user (maybe just moving the spawn and observable inside of the `do`), but I’ll figure it out.

---

<div class="post-metadata">

### Author: ![LeePhillips](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leephillips/32/205514_2.png) [@LeePhillips](https://discourse.julialang.org/u/LeePhillips)
#### Post date: [October 30, 2024, 6:02pm UTC](https://discourse.julialang.org/t/webpage-with-reactive-plot-animation/121570/4 "2024-10-30T18:02:44Z")

</div>

I’ve made a couple of interactive pages using what I think is a pretty general solution. It depends on HTTP.jl for communication and no web frameworks. Here’s the second one, that I just completed: [2D Vortex Dynamics](https://lee-phillips.org/vortex/).

You mentioned automatic updates of a plot, so my approach might be useful for you, because I use websockets, which let you continuously stream data from the Julia process into the page.

Another solution is the plutosliderserver.
