Skip to content

[Question] Can we display heatmap ? #60

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

Closed
terasakisatoshi opened this issue Sep 3, 2020 · 7 comments
Closed

[Question] Can we display heatmap ? #60

terasakisatoshi opened this issue Sep 3, 2020 · 7 comments
Assignees

Comments

@terasakisatoshi
Copy link

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)
@waralex
Copy link
Collaborator

waralex commented Sep 3, 2020

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]

@terasakisatoshi
Copy link
Author

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

@terasakisatoshi
Copy link
Author

terasakisatoshi commented Sep 3, 2020

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

@jackparmer
Copy link
Contributor

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/

@ndgnuh
Copy link

ndgnuh commented May 28, 2021

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.

@sglyon
Copy link
Contributor

sglyon commented Jul 30, 2021

@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

@sglyon
Copy link
Contributor

sglyon commented Aug 26, 2021

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

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

5 participants