Genie Discord forum

Author AvatarCeboc54
9/18/2023, 4:23:43 AM

Hi, I'm still learning the GenieFramework, and I want to plot the behavior of the function sine(x,A,k,ϕ) = A*sin(k*x + ϕ) asA, k or ϕ changes, as an example. I want to use Plots.jl because I'm more familiar with this package.

For app.jl

module App
# set up Genie development environment
using GenieFramework
@genietools

include("app/Sine.jl")
using .Sine

import PlotlyBase, PlotlyJS, Plots
Plots.plotlyjs()

# Define the range of x values
xs = range(-8π,8π,length=1000)

# Define a function to update the plot
function update_plot(A,k,ϕ)
    result = Sine.sine.(xs,A,k,ϕ)
    plot(xs,result,show=false)

    # Return the plot for display
    return PlotlyJS.plotly(p)
end

# Define default values for reactive variables
A_default = 0.0
k_default = 0.0
ϕ_default = 0.0

# add reactive code to make the UI interactive
@app begin
    # reactive variables are tagged with @in and @out
    @in A = 0.0
    @in k = 0.0
    @in ϕ = 0.0
    @out traces = update_plot(A,k,ϕ)
    
    @onchange A, k, ϕ begin
        traces = update_plot(A,k,ϕ)
    end
end

# register a new route and the page that will be
# loaded on access
@page("/", "app.jl.html")
end

and finally for app.jl.html

<h4>
</h4>
<h1> Sine function</h1>
<div class="row">
    <div class="st-col col-12 col-sm st-module">
        <p>
        </p>
        <h2>A</h2>
        <p></p>
        <q-slider v-model="A" :min="0.0" :max="10.0"></q-slider>
    </div>
    <div class="st-col col-12 col-sm st-module">
        <p>
        </p>
        <h2>k</h2>
        <p></p>
        <q-slider v-model="k"></q-slider>
    </div>
    <div class="st-col col-12 col-sm st-module">
        <p>
        </p>
        <h2>Φ</h2>
        <p></p>
        <q-slider v-model="ϕ" :min="-3" :max="3"></q-slider>
    </div>
</div>
<plotly :data="traces"></plotly>

But now I got a 404 error and this error: ERROR: UndefVarError: A not defined. What I'm doing wrong?

Author AvatarGenerallyClueless
9/18/2023, 1:12:01 PM

Are you using GenieBuilder plugin for VS Code? If not, then I suggest you try it. It's a nice GUI designer. Once you get it up and running, it's a very nice and organized way of building projects. Very easy to use. You can right click on the project and run package manager for the project rather than using includes.

In your Julia app... it looks like you defining the handlers without an @handlers begin.... end block.

using

@genietools @handlers begin # initialize reactive variables here @in A = A_default # reactive variable used in slider @in B = B_default # reactive variable used in another slider @out plot_data = 0 # reactive variable holding plot data to be sent from jl to js plot. ..... @onchange A, k, phi begin # event handler block traces = update_plot(A,k,phi) end # end onchange block

  @onchange AnotherVar begin
       Do="more stuff"
    end # end onchange block.. like a RESET button, for example

end # end handlers block

@page("/", "app.jl.html") end

Next..... your plot..... You want to pass the plot data to the plot object.

I do this using something along the lines of using a variable "plot_data" . Reactive variables must be defined and initialized within the @handlers block using @out macro in the case of plot_data or @in slider_var for sliders.

In the HTML code, you have to add the reactive variable in the HTML for the elements where they are used. For example:

    <div class="st-col col-12 col-sm st-module" style="max-width: 80%;">
        <h2>Plot of {{mySinEqn}}</h2>
        <plotly :data="plot_data"></plotly>
    </div>

Note: Pay attention to how reactive variables are used in HTML v-model=A.... not v-model:="A" plotly ="plot_data"

(using :="A" would make this interpreted as a quasar variable, not a reactive variable.... if I remember correctly)

Author AvatarGenerallyClueless
9/18/2023, 1:42:28 PM

Basically all of the work that I have done in Genie has been using GenieBuilder so my code probably shows that tendency. I do not know enough about HTML/CSS/JS/ other front end stuff and was never really interested to learn it. For me, GenieBuilder is really EXCELLENT because it takes care of all of this stuff that I don't like 😍 .

Thank you GENIE & GENIE BUILDER DEVS!!!

Author AvatarCeboc54
9/19/2023, 4:58:49 AM

It helps me understand what's going on in my code. And I discover something, I don't know how to extract the traces from a plot if it was made with Plots.jl.

Now, for the next code, if I comment the parts that involve the update_plot function, my code works. But when I tried to use the ideas from the Genie reference, I got an error. So I think the error comes from getting the traces.

Now, I realized how to plot such function, but using HTML in a very manual way. My idea is to later be able to plot more compex things, but to do so I need to plot using Plots.jl. In that way, I need a manner to translate a plot to something that Plotly understands.

The next version of the code works, but not as I intended.

Author AvatarCeboc54
9/19/2023, 4:58:57 AM

app.jl

module App
# set up Genie development environment
using GenieFramework
@genietools

include("app/Sine.jl")
using .Sine

import PlotlyBase, PlotlyJS, Plots
Plots.plotlyjs()

# Define the range of x values
xs = range(-8π,8π,length=1000)


function plotly_traces(plt::Plots.Plot)
    traces = PlotlyBase.GenericTrace[]
    for series_dict in Plots.plotly_series(plt)
        plotly_type = pop!(series_dict, :type)
        push!(traces, PlotlyBase.GenericTrace(plotly_type; series_dict...))
    end
    return traces
end

# Define a function to update the plot
function update_plot(A,k,ϕ)
    return Sine.sine.(xs,A,k,ϕ)
    #p = Plots.plot(xs,result,show=false)

    # Return the plot for display
    #return plotly_traces(p)
end

# Define default values for reactive variables
A_default = 0.0
k_default = 0.0
ϕ_default = 0.0

# add reactive code to make the UI interactive
@app begin
    # reactive variables are tagged with @in and @out
    @in A = A_default
    @in k = k_default
    @in ϕ = ϕ_default
    @out ys = update_plot(0.0,0.0,0.0)
    @out xs = xs
    
    @onchange A, k, ϕ begin
        ys = update_plot(A,k,ϕ)
        @show A
    end
end

# register a new route and the page that will be
# loaded on access
@page("/", "app.jl.html")
end
Author AvatarCeboc54
9/19/2023, 4:59:00 AM

app.jl.html

<h4>
</h4>
<h1> Sine function</h1>
<div class="row">
    <div class="st-col col-12 col-sm st-module">
        <p>
        </p>
        <h2>A = {{A}}</h2>
        <p></p>
        <q-slider v-model="A" :min="0.0" :max="10.0" :label="true" :step="0.1" :label-always="true"></q-slider>
    </div>
    <div class="st-col col-12 col-sm st-module">
        <p>
        </p>
        <h2>k = {{k}}</h2>
        <p></p>
        <q-slider v-model="k" :label="true" :min="0" :max="10" :step="0.1" :label-always="true"></q-slider>
    </div>
    <div class="st-col col-12 col-sm st-module">
        <p>
        </p>
        <h2>ϕ = {{ϕ}}</h2>
        <p></p>
        <q-slider v-model="ϕ" :min="-3" :max="3" :label="true" :step="0.1" :label-always="true"></q-slider>
    </div>
</div>
<plotly :data="[{x: xs,
    y: ys,
    mode: 'lines',
    type: 'lines',
    marker: { color: 'rgb(201, 90, 218)', size: 12 },
    line: { color: 'rgba(61, 185, 100, 0.8)', width: 1.5 }
}]"></plotly>
Author AvatarCeboc54
9/19/2023, 4:59:29 AM

sine.jl

module Sine
export sine

sine(x,A,k,ϕ) = A*sin(k*x + ϕ)

end
Author AvatarCeboc54
9/19/2023, 5:00:11 AM

Look that I'm not using at all the function plotly_traces

Author AvatarGenerallyClueless
9/19/2023, 11:53:37 AM

I think the challenge that you have now is rather than using Plots.jl you should be using a plotting library that supports reactivity. I have used StipplePlotly with great success.

If you are using Genie Builder Extension, then start the server, then the app, and right click on the app to add the package using the built-in package manager:

Author AvatarGenerallyClueless
9/19/2023, 12:13:50 PM

Also, check out StipplePlotly here: https://github.com/GenieFramework/StipplePlotly.jl

In code, it's as easy as: module App using GenieFramework using StipplePlotly @genietools @handlers begin... assume we use the same code that I put in my previous reply

 @onchange A,k,phi begin
      # StipplePlotly in HTML will take the reactive variable plot_data and update the plot accordingly
      # I'm not sure you need a separate function update_plot() at all.  I have plotted various functions and just used the broadcast operator "." on the x-axis data... like this...
      plot_data = PlotData(plot=StipplePlotly.Charts.PLOT_TYPE_LINE, x=xs, y=sine.(xs,A,k,phi)  )

end #handlers end @page("/", "app.jl.html") end #module end

---------------------------------------- Now HTML ---------------- My HTML was generated by GenieBuilder and all that I had to do was make certain that plot_data was passed as an argument to my StipplePlotly plot.

The bit null makes a nice HTML

title

for the plot .

Author AvatarPere
9/20/2023, 1:11:17 PM

@Ceboc54 we have documentation on how to plot with Plots.jl. Essentially you extract the traces and create a Plotly plot

https://learn.genieframework.com/docs/reference/reactive-ui/plotting

Author AvatarPere
9/20/2023, 1:13:18 PM

Although from your previous messages, it seems you'v already tried that but got an error? Which error?