plotly / Dash.jl

Dash for Julia - A Julia interface to the Dash ecosystem for creating analytic web applications in Julia. No JavaScript required.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Question] Can we display heatmap ?

terasakisatoshi opened this issue · comments

I would like to draw heatmap using Dash.jl like

http://juliaplots.org/PlotlyJS.jl/stable/examples/heatmaps/

The following code only displays diagonal elements

image

Here is my code to reproduce this issue

using Dash
using DashCoreComponents
using DashHtmlComponents
app =
    dash(external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"])
app.layout = html_div() do
    html_h1("Hello Dash"),
    html_div("Dash.jl: Julia interface for Dash"),
    dcc_graph(
        id = "example-graph",
        figure = (
            data = [
                (x = [1, 2, 3], y = [1, 2, 3], z = rand(3,3), type = "heatmap", name = "SF"),
            ],
            layout = (title = "Dash Data Visualization",),
        ),
    )
end

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

Hi, @terasakisatoshi !
Apparently this is the problem:

julia> JSON2.write(rand(1:3, 3,3))
"[3,1,3,1,1,3,1,1,1]"

Behavior of other JSON packages:

julia> JSON3.write(rand(1:3, 3,3))
"[1,2,2,3,2,1,1,1,1]"
julia> JSON.json(rand(1:3, 3,3))
"[[2,2,1],[1,3,1],[3,1,2]]"

Only JSON behaves adequately with the matrix, but I would not like to switch to it for a number of reasons. I still don't really understand what to do with this - apparently I will need to do PR in JSON2 (or do piracy inside Dash and overload the method for the matrix)

As a temporary not very beautiful solution I can offer:

z = [rand(3) for _ in 1:3]

Thank you @waralex .
I was trying (this is what I wanted) to display an image using Dash.jl via Plots.jl's API something like:

using Dash
using DashHtmlComponents
using DashCoreComponents

using Plots
plotly()

using Images
using TestImages

p = plot(imresize(testimage("mandrill"), 100,100))

data = Plots.plotly_series(p)
layout = Plots.plotly_layout(p)

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

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

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

Since Plots.jl uses heatmap to display image,Plots.plot(image) is almost equivalent to heatmap(image, yflip=true, colorbar=false, aspect_ratio=:equal).

image

On the other hand, due to Dash uses JSON2.write(matrix), it causes phenomena like 😅 :

image

It seems your temporary solution works to display an image (It is not cool though 😅 )

Code

using Dash
using DashHtmlComponents
using DashCoreComponents

using Plots
plotly()

using Images
using TestImages

p = plot(imresize(testimage("mandrill"), 100,100))

data = Plots.plotly_series(p)
data[1][:z] = [c for c in eachcol(data[1][:z])] # <-- As a temporary

layout = Plots.plotly_layout(p)

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

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

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

Result

image

Rather than the heatmap trace type, the ideal solution would be documenting the new imshow trace type for PlotlyJS.jl:

https://plotly.com/python/imshow/

commented

Can we just use PlotlyJS jl for figure? I mean, something like:

p = plot(traces, layout)
dcc_graph(; figure = p)

Because PlotlyJS plot have the same structure as the figure tuple.

@jackparmer and @ndgnuh you are on to something!!

Here is a working version of this example that uses the new image trace type in PlotlyJS.jl (what plotly.py's imshow is built on) to view the mandrill image:

using Dash
using DashHtmlComponents
using DashCoreComponents

using PlotlyJS

using Images
using TestImages

img = imresize(testimage("mandrill"), 100, 100)
p = plot(image(z=channelview(img') .* 255))

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

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

run_server(app, "127.0.0.1", 8080, debug=false)

A few notes:

  1. We need to use Images.channelview on the image to go from a Matrix of RGB types to a 3d array.
  2. We need to transpose the image before calling channelview because Julia is column-major while plotly.js is row major. :(
  3. Finally we need to multiply the output of channelview by 255 to put it on the [0, 255] scale expected by plotly.js javascript instead of the [0, 1] scale preferred by Images.jl

Good luck, please feel free to reopen (or comment!) if you have additional questions

Also see the new image docs!! https://plotly.com/julia/images/