Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Contributed Examples #50

Open
terasakisatoshi opened this issue Aug 6, 2020 · 17 comments
Open

Contributed Examples #50

terasakisatoshi opened this issue Aug 6, 2020 · 17 comments

Comments

@terasakisatoshi
Copy link

terasakisatoshi commented Aug 6, 2020

As well as Interact.jl Contributed Examples JuliaGizmos/Interact.jl#36 , it is good idea to collect examples using Dash.jl.

Here is my example

Code

# Usage: just run this code 
# tested on Julia 1.4 and 1.5 and 1.6-DEV

using Dash
using DashHtmlComponents
using DashCoreComponents
using Plots

function powplot(n)
    p = plot(x -> x^n, label = "y=x^$n", xlims=[0,1])
    figure = (data = Plots.plotly_series(p), layout = Plots.plotly_layout(p))
    figure
end

app =
    dash(external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"])

app.layout = html_div(style = Dict(:width => "50%")) do
    html_h1("Hello Dash"),
    html_div() do
        html_div("slider", style = (width = "10%", display = "inline-block")),
        html_div(dcc_slider(
            id = "slider",
            min = 0,
            max = 9,
            marks = Dict(i => "$i" for i = 0:9),
            value = 1,
        ),style = (width = "70%", display = "inline-block"))
    end,
    html_br(),
    dcc_graph(id = "power", figure = powplot(1))
end

callback!(app, Output("power", "figure"), Input("slider", "value")) do value
    powplot(value)
end

run_server(app)

Result

powslider

Updated 2022/3/5

It seems the current Dash.jl does not work the example above.
I've fixed the example as below:

using Dash
using PlotlyJS

#      Status `~/.julia/environments/v1.7/Project.toml`
#  [1b08a953] Dash v1.1.2

function powplot(n)
    x = 0:0.01:1
    y = x .^ n
    p = plot(x, y, mode="lines")
    p.plot 
end

app =
    dash(external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"])

app.layout = html_div(style = Dict(:width => "50%")) do
    html_h1("Hello Dash"),
    html_div() do
        html_div("slider", style = (width = "10%", display = "inline-block")),
        html_div(dcc_slider(
            id = "slider",
            min = 0,
            max = 9,
            marks = Dict(i => "$i" for i = 0:9),
            value = 1,
        ),style = (width = "70%", display = "inline-block"))
    end,
    html_br(),
    dcc_graph(id = "power", figure = powplot(1))
end

callback!(app, Output("power", "figure"), Input("slider", "value")) do value
    powplot(value)
end

run_server(app)
@waralex
Copy link
Collaborator

waralex commented Aug 6, 2020

Yes, this is a great idea, thank you!
I have a repository https://github.com/waralex/DashboardsExamples with examples using Dashboards (the progenitor of Dash). I think that after the release of the first version of Dash, I will rewrite all the examples in it using Dash. Maybe after that I will move it out of my github to plotly. @alexcjohnson , what do you think?

@terasakisatoshi
Copy link
Author

Hi @waralex , good to know there are lots of examples !!!

I have a repository https://github.com/waralex/DashboardsExamples with examples using Dashboards (the progenitor of Dash).

Here is a more complicated example using PlotlyJS.jl instead of Plots.jl.

Code

# sphere.jl

using Dash
using DashHtmlComponents
using DashCoreComponents

using PlotlyJS

function drawsphere(r, N, camera)
    traces = typeof(scatter3d())[]
    φ = range(0.0, 2π, length = N)
    for θ in range(0, 2π, length = N)
        x = @. r * sin(θ) * cos(φ)
        y = @. r * sin(θ) * sin(φ)
        z = repeat([r * cos(θ)], N)
        push!(
            traces,
            scatter3d(
                x = x,
                y = y,
                z = z,
                showlegend = false,
                mode = "markers",
                marker = attr(color = :blue),
            ),
        )
    end
    layout = Layout(scene = attr(camera = camera))
    p = plot(traces, layout)
    figure =
        (data = getfield.(p.plot.data, :fields), layout = p.plot.layout.fields)
    figure
end

INIT_CAMERA_ATTR = attr(
    up = attr(x = 0, y = 0, z = 1),
    center = attr(x = 0, y = 0, z = 0),
    eye = attr(x = 1.25, y = 1.25, z = 1.25),
    projection = attr(type = "projective"),
)

# Application
app =
    dash(external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"])

# Create Custom Widget
function create_slider(name; value = 0, min = 0, max = 1, step = 0.1)
    return html_div() do
        html_div(
            name,
            style = (width = "20%", display = "inline-block", padding = "2px"),
        ),
        html_div(
            min,
            style = (width = "5%", display = "inline-block", padding = "2px"),
        ),
        html_div(
            dcc_slider(
                id = name,
                min = min,
                max = max,
                step = step,
                value = value,
            ),
            style = (width = "60%", display = "inline-block"),
        ),
        html_div(
            max,
            style = (width = "5%", display = "inline-block", padding = "2px"),
        )
    end
end

md_string = """
  # Dash.jl

  - Dash for Julia - A Julia interface to the Dash ecosystem for creating analytic web applications in Julia.
  No JavaScript required.
  - This example shows how to control camera of PlotlyJS's object.
  See [JavaScript Figure Reference: layout.scene](https://plotly.com/javascript/reference/layout/scene/#layout-scene-camera) for more details. Enjoy Julia with Dash.jl !!!
  """

# Layout
app.layout = html_div() do
    dcc_markdown(md_string),
    html_h3("up"),
    html_div() do
        html_div(style = (width = "70%",)) do
            create_slider("x_up"),
            create_slider("y_up"),
            create_slider("z_up", value = 1)
        end
    end,
    html_h3("center"),
    html_div() do
        html_div(style = (width = "70%",)) do
            create_slider("x_center"),
            create_slider("y_center"),
            create_slider("z_center")
        end
    end,
    html_h3("eye"),
    html_div() do
        html_div(style = (width = "70%",)) do
            create_slider("x_eye", value = 1.25, max = 2),
            create_slider("y_eye", value = 1.25, max = 2),
            create_slider("z_eye", value = 1.25, max = 2)
        end
    end,
    dcc_graph(id = "sphere", figure = drawsphere(2.0, 20, INIT_CAMERA_ATTR))
end

callback!(
    app,
    Output("sphere", "figure"),
    [
        Input("x_up", "value"),
        Input("y_up", "value"),
        Input("z_up", "value"),
        Input("x_center", "value"),
        Input("y_center", "value"),
        Input("z_center", "value"),
        Input("x_eye", "value"),
        Input("y_eye", "value"),
        Input("z_eye", "value"),
    ],
) do up_x, up_y, up_z, center_x, center_y, center_z, eye_x, eye_y, eye_z
    camera = attr(
        up = attr(x = up_x, y = up_y, z = up_z),
        center = attr(x = center_x, y = center_y, z = center_z),
        eye = attr(x = eye_x, y = eye_y, z = eye_z),
        projection = attr(type = "projective"),
    )
    figure = drawsphere(2.0, 20, camera)
    figure
end

run_server(app)

Result

image

@Moelf
Copy link

Moelf commented Aug 12, 2020

is it correct to say nearly all plots that can be done with Plots.jl + plotly() backend can be plotted in Dash.jl by using Plots.plotly_series, Plots.plotly_layout technique?

@terasakisatoshi
Copy link
Author

In the examples I've tried, it works. Not sure "all" can do 😅

@terasakisatoshi
Copy link
Author

terasakisatoshi commented Aug 14, 2020

I've found If we would like to display image, we can't use Plots.plotly_series technique.
Here is a workaround that uses DashHtmlComponents.html_div(src=...). (However, it is not accurate for some images due to a kind of TypeError.)

Code

# imageviewer.jl

using Base64

using Dash
using DashCoreComponents
using DashHtmlComponents
using ImageShow
using Plots
using TestImages

const remotefiles = [
    "autumn_leaves.png" ,
    "blobs.gif" ,
    "cameraman.tif" ,
    "earth_apollo17.jpg" ,
    "fabio_color_256.png" ,
    "fabio_color_512.png" ,
    "fabio_gray_256.png" ,
    "fabio_gray_512.png" ,
    "hela-cells.tif" ,
    "house.tif" ,
    "jetplane.tif" ,
    "lake_color.tif" ,
    "lake_gray.tif" ,
    "lena_color_256.tif" ,
    "lena_color_512.tif" ,
    "lena_gray_256.tif" ,
    "lena_gray_512.tif" ,
    "lena_gray_16bit.png" ,
    "livingroom.tif" ,
    "lighthouse.png" ,
    "mandril_color.tif" ,
    "mandril_gray.tif" ,
    "mandrill.tiff" ,
    "m51.tif" ,
    "moonsurface.tiff" ,
    "mountainstream.png" ,
    "mri-stack.tif" ,
    "multi-channel-time-series.ome.tif" ,
    "peppers_color.tif" ,
    "peppers_gray.tif" ,
    "pirate.tif" ,
    "toucan.png" ,
    "walkbridge.tif" ,
    "woman_blonde.tif" ,
    "woman_darkhair.tif" ,
]

function encode(io::IOBuffer, img)
    io2=IOBuffer()
    b64pipe=Base64EncodePipe(io2)
    write(io,"data:image/png;base64,")
    show(b64pipe, MIME"image/png"(), img) # will be valid if we load ImageShow.jl
    write(io, read(seekstart(io2)))
end

function encode(file::AbstractString)
    img = testimage(file)
    io = IOBuffer()
    encode(io, img)
    String(take!(io))
end

app = dash(external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"])

app.layout = html_div() do 
    html_h1("ImageViewer using Dash.jl"),
    dcc_dropdown(
        id = "dropdown",
        options = [(label=f, value=f) for f in remotefiles],
        value = "cameraman.tif",
    ),
    html_img(id="viewer", src=encode("cameraman.tif"))
end

callback!(
    app,
    Output("viewer","src"),
    Input("dropdown","value"),
) do filename
    encode(filename)
end

run_server(app)

Result

goma

@terasakisatoshi
Copy link
Author

Check CPU Usage using Dash.jl

Real-time update application using dcc_interval

using Dash
using DashCoreComponents
using DashHtmlComponents

using PyCall

py"""
import psutil
"""

using Plots

const SECOND = 1000
interval = 0.5 * SECOND # msec
xmax = 60
tickstep = Int(xmax / interval * SECOND)
cpu_history = zeros(py"psutil.cpu_count(logical=True)")


app =
    dash(external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"])

    app.layout = html_div() do
    html_h1("Check CPU Usage using Dash.jl"),
    html_div("Dash.jl: Julia interface for Dash"),
    dcc_graph(id = "example-graph"),
    dcc_interval(
        id="interval-component",
        interval=interval,
        n_intervals=0,
    )
end

callback!(
    app,
    Output("example-graph","figure"),
    [Input("interval-component","n_intervals")],
) do n
    global cpu_history, interval
    percpu = py"psutil.cpu_percent(percpu=True)"
    cpu_history = hcat(cpu_history, percpu)
    cpu_history = cpu_history[begin:end, max(1,end-tickstep+1):end]
    _, len = cpu_history |> size
    p = plot(
        range(1,step=interval/SECOND,length=len),
        cpu_history',
        xlim=[0, xmax],
        ylim=[0, 100],
        label=:none,
        xticks = 0:10:xmax,
        yticks = 0:25:100,
    )
    figure = (data = Plots.plotly_series(p), layout = Plots.plotly_layout(p))
    figure
end

run_server(app, "127.0.0.1", 8050, debug = true)

Screen Shot 2020-08-29 at 13 22 06

@PallHaraldsson
Copy link
Contributor

PallHaraldsson commented Sep 2, 2020

I like the look of these examples, but they didn't work for me (neither those in the readme), e.g. because of the code stating with the line:

INIT_CAMERA_ATTR = attr(

[..]

ERROR: UndefVarError: attr not defined
Stacktrace:
 [1] top-level scope at REPL[71]:1

I probably have a setup problem but I do neot even find the function here in the repository.

@terasakisatoshi
Copy link
Author

@PallHaraldsson Did you install PlotlyJS correctly ? attr is exported by PlotlyJS.

@caseykneale
Copy link

Check CPU Usage using Dash.jl

Real-time update application using dcc_interval

Is there anyway to get custom legend labels for this example? IE: Trace 1, Trace 2, Trace 3...? I blew like 2 hrs failing to do so

@terasakisatoshi
Copy link
Author

Hi, @caseykneale

How about this code?

    cpu_count = py"psutil.cpu_count(logical=True)"
    label = reshape(["Trace $(c)" for c in 1:cpu_count], 1, cpu_count)
    p = plot(
        range(1,step=interval/SECOND,length=len),
        cpu_history',
        xlim=[0, xmax],
        ylim=[0, 100],
        xticks = 0:10:xmax,
        yticks = 0:25:100,
        label=label,
    )

This will get

image

note that plot function is exported by Plots.jl (not Dash.jl)

This link https://docs.juliaplots.org/latest/tutorial/#Plot-Attributes might help you.

@caseykneale
Copy link

Works well thank you! Seems like we still have the issue of PlotlyJS eating plot margins for x and y axis labels. But that's another issue for another day. Thanks you for explaining how to use the Plots.plot rather then the Dash.plot

@terasakisatoshi
Copy link
Author

terasakisatoshi commented Jun 6, 2021

Compare code A and code B

  • We can see the difference between codeA: sum((1,2,3,4)) and codeB sum([1,2,3,4]) and will find that the former is better than latter.
  • We'll also find there is a great package named DashBootstrapComponents.jl.

Code

# app.jl
using Dash
using DashHtmlComponents
using DashCoreComponents
using DashBootstrapComponents

using IOCapture
using InteractiveUtils:clipboard

app = dash(external_stylesheets=[dbc_themes.BOOTSTRAP])
# app = dash(external_stylesheets=["https://codepen.io/chriddyp/pen/bWLwgP.css"])
app.layout = dbc_container(className="mxy-auto") do
    html_h1("Compare code A with B?"),
    html_div("Put your code before including codeA and codeB"),
    dcc_textarea(
        id="text-code-common",
        placeholder="common code",
        rows=10,
        style=Dict(:width => "100%"),
    ),
    html_div(id="result-common"),
    dbc_row(
        [
            dbc_col(dcc_textarea(
                id="text-codeA",
                placeholder="codeA",
                value="",
                rows=2,
                style=Dict(:width => "100%"),
            )),
            dbc_col(dcc_textarea(
                id="text-codeB",
                placeholder="codeB",
                value="",
                rows=2,
                style=Dict(:width => "100%"),
            ))
        ],
    ),
    dbc_row(
        [
            dbc_col(dbc_button("Compare", id="button-compare", block=true, color="primary", className="margin-auto", size="sm")),
        ],
    ),
    html_h3("Result", style=Dict("text-align" => "center")),
    dbc_row(
        [
            dbc_col(dcc_textarea(
                id="text-resultA",
                placeholder="resultA",
                value="",
                rows=10,
                readOnly=true,
                style=Dict(:width => "100%"),
            )),
            dbc_col(dcc_textarea(
                id="text-resultB",
                placeholder="resultB",
                value="",
                rows=10,
                readOnly=true,
                style=Dict(:width => "100%"),
            ))
        ],
    ),
    dbc_row(
        [
            dbc_col(dbc_button("Copy result A", id="button-copyA", color="primary")),
            dbc_col(dbc_button("Copy result B", id="button-copyB", color="primary")),
        ],
    ),
    html_div("dummy-resultA", id="dummy-resultA", style=Dict("display" => "none")),
    html_div("dummy-resultB", id="dummy-resultB", style=Dict("display" => "none")),
    html_div("dummy-codeA", id="dummy-codeA", style=Dict("display" => "none")),
    html_div("dummy-codeB", id="dummy-codeB", style=Dict("display" => "none"))
end

# Taken from Literate.jl and modified
function sandbox()
    m = Module(gensym())
    # eval(expr) is available in the REPL (i.e. Main) so we emulate that for the sandbox
    Core.eval(m, :(eval(x) = Core.eval($m, x)))
    # modules created with Module() does not have include defined
    # abspath is needed since this will call `include_relative`
    Core.eval(m, :(include(x) = Base.include($m, abspath(x))))
    # load InteractiveUtils
    Core.eval(m, :(using InteractiveUtils))
    return m
end

sb = sandbox()

callback!(
    app,
    [Output("text-resultA", "value"), Output("text-resultB", "value"), Output("result-common", "children")],
    Input("button-compare", "n_clicks"),
    [State("text-codeA", "value"), State("text-codeB", "value"), State("text-code-common", "value")],
) do n_clicks, vA, vB, vCommon
    if isnothing(n_clicks) || n_clicks == 0
        return (nothing, nothing, nothing)
    end

    cCommon = IOCapture.capture(rethrow=Union{}) do
        include_string(sb, vCommon)
    end
    retC = nothing
    if !isnothing(vCommon) && cCommon.error
        retC = """
        $(sprint(showerror, cCommon.value))
        when executing the following code block
        ```julia
        $vCommon
        ```
        """
        @warn "$retC"
    else
        retC = nothing
    end

    cA = IOCapture.capture(rethrow=Union{}) do
        include_string(sb, vA)
    end
    cB = IOCapture.capture(rethrow=Union{}) do
        include_string(sb, vB)
    end


    if cA.error
        retA = """
        $(sprint(showerror, cA.value))
        when executing the following code block
        ```julia
        $vA
        ```
        """
    else
        retA = cA.output
    end

    if cB.error
        retB = """
        $(sprint(showerror, cB.value))
        when executing the following code block
        ```julia
        $vB
        ```
        """
    else
        retB = cB.output
    end

    return (retA, retB, retC)
end

callback!(
    app,
    Output("dummy-resultA", "children"),
    Input("button-copyA", "n_clicks"),
    State("text-resultA", "value"),
) do n_clicks, value
    if !isnothing(n_clicks) && n_clicks > 0
        return clipboard(value)
    end
end

callback!(
    app,
    Output("dummy-resultB", "children"),
    Input("button-copyB", "n_clicks"),
    State("text-resultB", "value"),
) do n_clicks, value
    if !isnothing(n_clicks) && n_clicks > 0
        return clipboard(value)
    end
end

run_server(app, debug=true)

Usage

  • Install Dash, DashCoreComponents, DashHtmlComponents, DashBootstrapComponents and IOCapture
  • julia app.jl

Result

image

image

Edit

Updated at 2022/08/14

# app.jl
using Dash
using DashBootstrapComponents

using IOCapture
using InteractiveUtils: clipboard

app = dash(external_stylesheets = [dbc_themes.BOOTSTRAP])

app.layout = dbc_container(className = "mxy-auto") do
    html_h1("Compare code A with B?"),
    html_div("Put your code before including codeA and codeB"),
    dcc_textarea(
        id = "text-code-common",
        placeholder = "common code",
        rows = 10,
        style = Dict(:width => "100%"),
    ),
    html_div(id = "result-common"),
    dbc_row([
        dbc_col([
            html_h2("codeA"),
            dcc_textarea(
                id = "text-codeA",
                placeholder = "codeA",
                value = "",
                rows = 2,
                style = Dict(:width => "100%"),
            ),
        ]),
        dbc_col([
            html_h2("codeB"),
            dcc_textarea(
                id = "text-codeB",
                placeholder = "codeB",
                value = "",
                rows = 2,
                style = Dict(:width => "100%"),
            ),
        ]),
    ],),
    dbc_row([
        dbc_col(
            dbc_button(
                "Compare",
                id = "button-compare",
                color = "primary",
                className = "margin-auto",
                size = "sm",
            ),
        ),
    ],),
    html_h3("Result", style = Dict("text-align" => "center")),
    dbc_row([
        dbc_col(
            dcc_textarea(
                id = "text-resultA",
                placeholder = "resultA",
                value = "",
                rows = 10,
                readOnly = true,
                style = Dict(:width => "100%"),
            ),
        ),
        dbc_col(
            dcc_textarea(
                id = "text-resultB",
                placeholder = "resultB",
                value = "",
                rows = 10,
                readOnly = true,
                style = Dict(:width => "100%"),
            ),
        ),
    ],),
    dbc_row([
        dbc_col(dbc_button("Copy result A", id = "button-copyA", color = "primary")),
        dbc_col(dbc_button("Copy result B", id = "button-copyB", color = "primary")),
    ],),
    html_div("dummy-resultA", id = "dummy-resultA", style = Dict("display" => "none")),
    html_div("dummy-resultB", id = "dummy-resultB", style = Dict("display" => "none")),
    html_div("dummy-codeA", id = "dummy-codeA", style = Dict("display" => "none")),
    html_div("dummy-codeB", id = "dummy-codeB", style = Dict("display" => "none"))
end

# Taken from Literate.jl and modified
function sandbox()
    m = Module(gensym())
    # eval(expr) is available in the REPL (i.e. Main) so we emulate that for the sandbox
    Core.eval(m, :(eval(x) = Core.eval($m, x)))
    # modules created with Module() does not have include defined
    # abspath is needed since this will call `include_relative`
    Core.eval(m, :(include(x) = Base.include($m, abspath(x))))
    # load InteractiveUtils
    Core.eval(m, :(using InteractiveUtils))
    return m
end

sb = sandbox()

callback!(
    app,
    [
        Output("text-resultA", "value"),
        Output("text-resultB", "value"),
        Output("result-common", "children"),
    ],
    Input("button-compare", "n_clicks"),
    [
        State("text-codeA", "value"),
        State("text-codeB", "value"),
        State("text-code-common", "value"),
    ],
) do n_clicks, vA, vB, vCommon
    if isnothing(n_clicks) || n_clicks == 0
        return (nothing, nothing, nothing)
    end

    cCommon = IOCapture.capture(rethrow = Union{}) do
        include_string(sb, vCommon)
    end
    retC = nothing
    if !isnothing(vCommon) && cCommon.error
        retC = """
        $(sprint(showerror, cCommon.value))
        when executing the following code block
        ```julia
        $vCommon
        ```
        """
        @warn "$retC"
    else
        retC = nothing
    end

    cA = IOCapture.capture(rethrow = Union{}) do
        include_string(sb, vA)
    end
    cB = IOCapture.capture(rethrow = Union{}) do
        include_string(sb, vB)
    end


    if cA.error
        retA = """
        $(sprint(showerror, cA.value))
        when executing the following code block
        ```julia
        $vA
        ```
        """
    else
        retA = cA.output
    end

    if cB.error
        retB = """
        $(sprint(showerror, cB.value))
        when executing the following code block
        ```julia
        $vB
        ```
        """
    else
        retB = cB.output
    end

    return (retA, retB, retC)
end

callback!(
    app,
    Output("dummy-resultA", "children"),
    Input("button-copyA", "n_clicks"),
    State("text-resultA", "value"),
) do n_clicks, value
    if !isnothing(n_clicks) && n_clicks > 0
        return clipboard(value)
    end
end

callback!(
    app,
    Output("dummy-resultB", "children"),
    Input("button-copyB", "n_clicks"),
    State("text-resultB", "value"),
) do n_clicks, value
    if !isnothing(n_clicks) && n_clicks > 0
        return clipboard(value)
    end
end

run_server(app, debug = true)

@john-waczak
Copy link

Is there a way to get the y-axis and the y-ticks to show up?

@jorge-jardim
Copy link

Works well thank you! Seems like we still have the issue of PlotlyJS eating plot margins for x and y axis labels. But that's another issue for another day. Thanks you for explaining how to use the Plots.plot rather then the Dash.plot

Is there a way to get the y-axis and the y-ticks to show up?

Im facing the same problem.

@terasakisatoshi
Copy link
Author

Hi, I've created a Julia package PyPlotly.jl which is Pythonista friendly Julia user interface for plotly. Now we can write a Julia code as if it is written in Python. Of course we use from Dash.jl !!! Below is an example:

using Dash

using PyPlotly
using JSON3

app = dash(external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"])

fig = go.Figure(
    data=[
    go.Bar(x=[1,2,3], y = [4,1,2], name="SF"),
    go.Bar(x = [1,2,3], y = [2,4,5], name="Montréal")
    ],
    layout = go.Layout(title = "Dash Data Visualization"),
)

jsonobj = JSON3.read_json_str(fig.to_json())
data = jsonobj["data"]
layout = jsonobj["layout"]

app.layout = html_div() do
        html_h1("Hello Dash"),
        html_div("PyPlotly.jl: Julia interface for Plotly"),
        dcc_graph(
            id = "example-graph",
            figure = (data=data, layout=layout)
        )
end

run_server(app, "127.0.0.1", 8080)

image

@terasakisatoshi
Copy link
Author

@jorge-jardim FYI

using Dash

using PyPlotly
using JSON3
using PyCall

py"""
import psutil
"""

using Plots

const SECOND = 1000
interval = 0.5 * SECOND # msec
xmax = 60
tickstep = Int(xmax / interval * SECOND)
cpu_history = zeros(py"psutil.cpu_count(logical=True)")


app =
    dash(external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"])

    app.layout = html_div() do
    html_h1("Check CPU Usage using Dash.jl"),
    html_div("Dash.jl: Julia interface for Dash"),
    html_div("PyPlotly.jl: Pythonista friendly Julia interface for Plotly"),
    dcc_graph(id = "example-graph"),
    dcc_interval(
        id="interval-component",
        interval=interval,
        n_intervals=0,
    )
end

callback!(
    app,
    Output("example-graph","figure"),
    [Input("interval-component","n_intervals")],
) do n
    global cpu_history, interval
    percpu = py"psutil.cpu_percent(percpu=True)"
    cpu_history = hcat(cpu_history, percpu)
    cpu_history = cpu_history[begin:end, max(1,end-tickstep+1):end]
    n, len = cpu_history |> size

    xs = range(1,step=interval/SECOND,length=len) |> collect
    ys = Matrix(cpu_history)

    fig=go.Figure()
    for i in 1:n
        fig.add_trace(
            go.Scatter(
                x=xs,
                y=ys[i, :],
                mode="lines",
                name="$i",
            )
        )
    end
    fig.update_xaxes(title_text="Time", range=[1,xmax])
    fig.update_yaxes(title_text="Percent")
    fig.update_layout(
        xaxis = Dict(
            :tickmode => "linear",
            :tick0 => 0.,
            :dtick => 10,
        ),
        yaxis=Dict(
            :tickmode => "linear",
            :tick0 => 0.,
            :dtick => 25,
        )
    )

    jsonobj = JSON3.read_json_str(fig.to_json())
    data = jsonobj["data"]
    layout = jsonobj["layout"]

    figure=(data=data, layout=layout)
    figure
end

run_server(app, "127.0.0.1", 8080)

image

@jaboaf
Copy link

jaboaf commented Aug 18, 2023

nice job everyone. really.
i used dash a while back when i was just getting going with data + computers in python and managed to get the hang of it after a little trial and error and really appreciated how far it got me. managed to actually deploy some analytics (essentially statistics in python).
moved to julia that summer(2019).
was poking around today wondering what the web-app/gui front was like in julia cause, well, the REPL... is the REPL. anyways CLAPS TO YALL for being awesome. i hope to take the julia version of dash for a spin in the next few, will put anything i can muster here. ✌️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants