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

[FR] make a backend object ready-to-plot without rendering #3827

Closed
JinraeKim opened this issue Sep 18, 2021 · 3 comments
Closed

[FR] make a backend object ready-to-plot without rendering #3827

JinraeKim opened this issue Sep 18, 2021 · 3 comments

Comments

@JinraeKim
Copy link

Hi, I'd like to use Plots.jl with Dash.jl.

If I run the following code, I can see the figure interactively through a browser but an annoying rendered image also appears like this:

image

But if I comment out the display(fig) in the callback,
it seems not to construct a backend object so the figure not appeared through a browser, e.g., 127.0.0.1:8050.

If it's possible to update the backend object without displaying a figure on my computer, it would be possible to display a figure on my browser interactively without annoying rendered image while keeping the APIs of Plots.jl.

using Plots
using Dash, DashHtmlComponents, DashCoreComponents

function main()
    plotlyjs()
    app = dash()
    θs = 1:10 |> collect
    app.layout = html_div() do
        dcc_graph(id="graph"),
        dcc_slider(
            id="θ-slider",
            min=minimum(θs),
            max=maximum(θs),
            marks=Dict([Symbol(v) => Symbol(v) for v in θs]),
            value=minimum(θs),
            step=nothing,
        )
    end
    callback!(app, Output("graph", "figure"), Input("θ-slider", "value"),) do θ
        fig = Plots.plot()
        Plots.plot!(fig, θs, θ*ones(size(θs)))
        display(fig)
        Plots.backend_object(fig)
    end
    run_server(app, "0.0.0.0", debug=true)
end
@JinraeKim
Copy link
Author

Ah, there is already the functionality that I wanted.

Corrected code is

using Plots
using Dash, DashHtmlComponents, DashCoreComponents

function main()
    plotlyjs()
    app = dash()
    θs = 1:10 |> collect
    app.layout = html_div() do
        dcc_graph(id="graph"),
        dcc_slider(
            id="θ-slider",
            min=minimum(θs),
            max=maximum(θs),
            marks=Dict([Symbol(v) => Symbol(v) for v in θs]),
            value=minimum(θs),
            step=nothing,
        )
    end
    callback!(app, Output("graph", "figure"), Input("θ-slider", "value"),) do θ
        fig = Plots.plot()
        Plots.plot!(fig, θs, θ*ones(size(θs)))
        Plots.plotlyjs_syncplot(fig)
        Plots.backend_object(fig)
    end
    run_server(app, "0.0.0.0", debug=true)
end

@diegozea
Copy link
Contributor

diegozea commented Feb 2, 2022

Hi @JinraeKim ! I have noticed that this example is no longer working with the latest dash version. Also, DashHtmlComponents and DashCoreComponents have been deprecated and integrated into Dash. This is the error I am seeing:

julia> using Dash, DashHtmlComponents, DashCoreComponents
┌ Warning: The `DashHtmlComponents` package is deprecated. All DashHtmlComponents functions have been moved to the Dash package. Please switch to `using Dash` instead.
└ @ DashHtmlComponents ~/.julia/packages/DashHtmlComponents/bHm4X/src/DashHtmlComponents.jl:3
┌ Warning: The `DashCoreComponents` package is deprecated. All DashCoreComponents functions have been moved to the Dash package. Please switch to `using Dash` instead.
└ @ DashCoreComponents ~/.julia/packages/DashCoreComponents/Dli7Q/src/DashCoreComponents.jl:3
julia> main()
┌ Warning: Hot reloading is disabled for interactive sessions. Please run your app using julia from the command line to take advantage of this feature.
└ @ Dash ~/.julia/packages/Dash/soFjZ/src/server.jl:60
[ Info: Listening on: 0.0.0.0:8050
┌ Error: error handling request
│   exception =
│    ArgumentError: PlotlyJS.SyncPlot doesn't have a defined `StructTypes.StructType`
│    Stacktrace:
│      [1] write(::StructTypes.NoStructType, buf::Vector{UInt8}, pos::Int64, len::Int64, ::PlotlyJS.SyncPlot; kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
│        @ JSON3 ~/.julia/packages/JSON3/tqMvg/src/write.jl:91
│      [2] write(::StructTypes.NoStructType, buf::Vector{UInt8}, pos::Int64, len::Int64, ::PlotlyJS.SyncPlot)
│        @ JSON3 ~/.julia/packages/JSON3/tqMvg/src/write.jl:91
│      [3] write(::StructTypes.DictType, buf::Vector{UInt8}, pos::Int64, len::Int64, x::Dict{Symbol, Any}; kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
│        @ JSON3 ~/.julia/packages/JSON3/tqMvg/src/write.jl:155
│      [4] write(::StructTypes.DictType, buf::Vector{UInt8}, pos::Int64, len::Int64, x::Dict{Symbol, Any})
│        @ JSON3 ~/.julia/packages/JSON3/tqMvg/src/write.jl:146
│      [5] write(::StructTypes.DictType, buf::Vector{UInt8}, pos::Int64, len::Int64, x::Dict{String, Any}; kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
│        @ JSON3 ~/.julia/packages/JSON3/tqMvg/src/write.jl:155
│      [6] write(::StructTypes.DictType, buf::Vector{UInt8}, pos::Int64, len::Int64, x::Dict{String, Any})
│        @ JSON3 ~/.julia/packages/JSON3/tqMvg/src/write.jl:146
│      [7] write(::StructTypes.DictType, buf::Vector{UInt8}, pos::Int64, len::Int64, x::Dict{Symbol, Any}; kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
│        @ JSON3 ~/.julia/packages/JSON3/tqMvg/src/write.jl:155
│      [8] write
│        @ ~/.julia/packages/JSON3/tqMvg/src/write.jl:146 [inlined]
│      [9] write(obj::Dict{Symbol, Any}; kw::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
│        @ JSON3 ~/.julia/packages/JSON3/tqMvg/src/write.jl:39
│     [10] write(obj::Dict{Symbol, Any})
│        @ JSON3 ~/.julia/packages/JSON3/tqMvg/src/write.jl:37
│     [11] process_callback(request::HTTP.Messages.Request, state::Dash.HandlerState)
│        @ Dash ~/.julia/packages/Dash/soFjZ/src/handler/processors/callback.jl:78
│     [12] try_handle
│        @ ~/.julia/packages/Dash/soFjZ/src/HttpHelpers/router.jl:51 [inlined]
│     [13] try_handle(route::Dash.HttpHelpers.Route{Dash.HttpHelpers.RouteHandler{Dash.HttpHelpers.StaticRoute, typeof(Dash.process_callback)}}, path::SubString{String}, request::HTTP.Messages.Request, args::Dash.HandlerState)
│        @ Dash.HttpHelpers ~/.julia/packages/Dash/soFjZ/src/HttpHelpers/router.jl:97
│     [14] _handle
│        @ ~/.julia/packages/Dash/soFjZ/src/HttpHelpers/router.jl:101 [inlined]
│     [15] _handle (repeats 6 times)
│        @ ~/.julia/packages/Dash/soFjZ/src/HttpHelpers/router.jl:102 [inlined]
│     [16] handle(route_tuple::Tuple{Dash.HttpHelpers.Route{Dash.HttpHelpers.RouteHandler{Dash.HttpHelpers.StaticRoute, typeof(Dash.process_layout)}}, Dash.HttpHelpers.Route{Dash.HttpHelpers.RouteHandler{Dash.HttpHelpers.StaticRoute, typeof(Dash.process_dependencies)}}, Dash.HttpHelpers.Route{Dash.HttpHelpers.RouteHandler{Dash.HttpHelpers.StaticRoute, typeof(Dash.process_reload_hash)}}, Dash.HttpHelpers.Route{Dash.HttpHelpers.RouteHandler{Dash.HttpHelpers.StaticRoute, typeof(Dash.process_default_favicon)}}, Dash.HttpHelpers.Route{Dash.HttpHelpers.RouteHandler{Dash.HttpHelpers.DynamicRoute{Tuple{Tuple{Int64, String}}, NamedTuple{(:path, :namespace), Tuple{Int64, Int64}}}, typeof(Dash.process_resource)}}, Dash.HttpHelpers.Route{Dash.HttpHelpers.RouteHandler{Dash.HttpHelpers.DynamicRoute{Tuple{Tuple{Int64, String}}, NamedTuple{(:file_path,), Tuple{Int64}}}, typeof(Dash.process_assets)}}, Dash.HttpHelpers.Route{Dash.HttpHelpers.RouteHandler{Dash.HttpHelpers.StaticRoute, typeof(Dash.process_callback)}}, Dash.HttpHelpers.Route{Dash.HttpHelpers.RouteHandler{Dash.HttpHelpers.DynamicRoute{Tuple{}, NamedTuple{(), Tuple{}}}, typeof(Dash.process_index)}}, Dash.HttpHelpers.Route{Dash.HttpHelpers.RouteHandler{Dash.HttpHelpers.StaticRoute, typeof(Dash.process_index)}}}, path::SubString{String}, request::HTTP.Messages.Request, args::Dash.HandlerState)
│        @ Dash.HttpHelpers ~/.julia/packages/Dash/soFjZ/src/HttpHelpers/router.jl:112
│     [17] handle(router::Dash.HttpHelpers.Router, request::HTTP.Messages.Request, args::Dash.HandlerState)
│        @ Dash.HttpHelpers ~/.julia/packages/Dash/soFjZ/src/HttpHelpers/router.jl:129
│     [18] (::Dash.HttpHelpers.var"#1#2"{Dash.HttpHelpers.Router, Dash.HandlerState})(::HTTP.Messages.Request)
│        @ Dash.HttpHelpers ~/.julia/packages/Dash/soFjZ/src/HttpHelpers/handlers.jl:4
│     [19] handle
│        @ ~/.julia/packages/HTTP/aTjcj/src/Handlers.jl:254 [inlined]
│     [20] (::Dash.HttpHelpers.var"#7#8"{Dash.var"#67#69"{Dash.DashApp}, HTTP.Handlers.RequestHandlerFunction{Dash.HttpHelpers.var"#1#2"{Dash.HttpHelpers.Router, Dash.HandlerState}}})(::HTTP.Messages.Request)
│        @ Dash.HttpHelpers ~/.julia/packages/Dash/soFjZ/src/HttpHelpers/handlers.jl:48
│     [21] handle
│        @ ~/.julia/packages/HTTP/aTjcj/src/Handlers.jl:254 [inlined]
│     [22] (::Dash.HttpHelpers.var"#4#5"{Vector{String}, Int64, HTTP.Handlers.RequestHandlerFunction{Dash.HttpHelpers.var"#7#8"{Dash.var"#67#69"{Dash.DashApp}, HTTP.Handlers.RequestHandlerFunction{Dash.HttpHelpers.var"#1#2"{Dash.HttpHelpers.Router, Dash.HandlerState}}}}})(::HTTP.Messages.Request)
│        @ Dash.HttpHelpers ~/.julia/packages/Dash/soFjZ/src/HttpHelpers/handlers.jl:27
│     [23] handle
│        @ ~/.julia/packages/HTTP/aTjcj/src/Handlers.jl:254 [inlined]
│     [24] handle(::HTTP.Handlers.RequestHandlerFunction{Dash.HttpHelpers.var"#4#5"{Vector{String}, Int64, HTTP.Handlers.RequestHandlerFunction{Dash.HttpHelpers.var"#7#8"{Dash.var"#67#69"{Dash.DashApp}, HTTP.Handlers.RequestHandlerFunction{Dash.HttpHelpers.var"#1#2"{Dash.HttpHelpers.Router, Dash.HandlerState}}}}}}, ::HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}})
│        @ HTTP.Handlers ~/.julia/packages/HTTP/aTjcj/src/Handlers.jl:277
│     [25] #4
│        @ ~/.julia/packages/HTTP/aTjcj/src/Handlers.jl:351 [inlined]
│     [26] macro expansion
│        @ ~/.julia/packages/HTTP/aTjcj/src/Servers.jl:415 [inlined]
│     [27] (::HTTP.Servers.var"#13#14"{HTTP.Handlers.var"#4#5"{HTTP.Handlers.RequestHandlerFunction{Dash.HttpHelpers.var"#4#5"{Vector{String}, Int64, HTTP.Handlers.RequestHandlerFunction{Dash.HttpHelpers.var"#7#8"{Dash.var"#67#69"{Dash.DashApp}, HTTP.Handlers.RequestHandlerFunction{Dash.HttpHelpers.var"#1#2"{Dash.HttpHelpers.Router, Dash.HandlerState}}}}}}}, HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}, HTTP.Servers.Server{Nothing, Sockets.TCPServer}, HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.ConnectionPool.Transaction{Sockets.TCPSocket}}})()
│        @ HTTP.Servers ./task.jl:411
└ @ Dash ~/.julia/packages/Dash/soFjZ/src/handler/make_handler.jl:112

This is what I am seeing:

image

Using these packages:

  [1b08a953] Dash v1.1.1
  [1b08a953] DashCoreComponents v2.0.0
  [1b08a953] DashHtmlComponents v2.0.0
  [91a5bcdd] Plots v1.25.7

Do you know what is it the problem and how it can be fixed?

Thanks in advance,

Best regards,

@JinraeKim
Copy link
Author

@diegozea I think you'd better report this issue to Dash.jl developers as it seems due to the change of Dash's API.

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

2 participants