Dash.jl icon indicating copy to clipboard operation
Dash.jl copied to clipboard

Contour plot with different length axes displays incorrectly

Open chaseleslie opened this issue 4 years ago • 4 comments

When using a contour plot with x and y axes of different length (but the same range of values), the plot does not display with correct range:

using Dash, DashHtmlComponents, DashCoreComponents

axismax = 40
xdata = Float64[k for k in 0:2:axismax]
ydata = Float64[k for k in 0:axismax]
zdata = rand(Float64, length(ydata), length(xdata))

app = dash()
app.layout = html_div() do
    html_h1("Contour Range Demo"),
    dcc_graph(figure=(
        data=[(
            type="contour",
            x=xdata,
            y=ydata,
            z=zdata
        )],
        layout=(
            width=600,
            height=600
        )
    ))
end

run_server(app, "0.0.0.0", debug=true)

yields the following plot (notice the y axis only spans from [0,20]): contour_julia_autorange

Whereas an analogous python implementation:

import dash
import dash_core_components as dcc
import dash_html_components as html
import numpy as np

axismax = 40
xdata = [k for k in range(0, axismax + 1, 2)]
ydata = [k for k in range(0, axismax + 1)]
zdata = np.random.rand(len(ydata), len(xdata))

app = dash.Dash(__name__)
app.layout = html.Div([
    html.H1(children="Contour Range Demo"),
    dcc.Graph(figure={
        "data": [{
            "type": "contour",
            "x": xdata,
            "y": ydata,
            "z": zdata
        }],
        "layout": {
            "width": 600,
            "height": 600
        }
    })
])

if __name__ == '__main__':
    app.run_server(debug=True)

results in the desired plot with full range of axes (notice y axis goes from [0, 40]):

contour_julia_range

If the range attribute of the figure layout is set manually in Julia Dash:

dcc_graph(figure=(
        data=[(
            type="contour",
            x=xdata,
            y=ydata,
            z=zdata
        )],
        layout=(
            width=600,
            height=600
            xaxis=(range=[0,axismax],),
            yaxis=(range=[0,axismax],)
        )
    ))

then the plot still does not show the full y axis (only shows from [0,20]): contour_python_autorange

Using

  • Julia v1.5.3
  • Dash v0.1.3
  • DashCoreComponents v1.12.0
  • DashHtmlComponents v1.1.1

chaseleslie avatar Feb 22 '21 03:02 chaseleslie

Very interesting. The Julia and Python versions should be the exact same, since they are using the same underlying JavaScript renderer (Plotly.js). Perhaps PlotlyBase is using a different Plotly.js version, or perhaps something related to the axes bounds is not being serialized correctly.

jackparmer avatar May 27 '21 03:05 jackparmer

Hey @chaseleslie thanks for bringing this up...

The issue here is actually a bit subtle and technical. Julia arrays a column major, meaning you move down all of column 1 before starting on column 2. Python and javascript, on the other hand, are row major -- meaning you move across all of row 1 before moving to row 2

What this amounts to is the need to transpose the z argument so that when plotly.js gets it (in javascript land) it will be properly lined up.

This is something that has come up quite a few times in the past few years. I've always been hesitant to overload the call to heatmap on the julia side to insert this transpose, but perhaps it is time.

What do you think @jackparmer ?

NOTE: this would also be required for any trace type/attribute accepting a 2d-array, not just for contour.z

sglyon avatar Jul 30 '21 19:07 sglyon

oh and in case it is helpful... here is a Dash.jl codeblock that works just like the Python one

using Dash, DashHtmlComponents, DashCoreComponents, PlotlyJS

axismax = 40
xdata = Float64[k for k in 0:2:axismax]
ydata = Float64[k for k in 0:axismax]
zdata = rand(Float64, length(ydata), length(xdata))

app = dash()
app.layout = html_div() do
    html_h1("Contour Range Demo"),
    dcc_graph(figure=plot(
        contour(x=xdata, y=ydata, z=zdata'),
        Layout(width=600, height=600)
    ))
end

run_server(app, "0.0.0.0", 8049, debug=false)

sglyon avatar Jul 30 '21 19:07 sglyon

Yes I think it’s a good idea We want to make things as natural and ergonomic as possible for Julia users

Sent from my iPhone

On Jul 30, 2021, at 12:33 PM, Spencer Lyon @.***> wrote:

 Hey @chaseleslie thanks for bringing this up...

The issue here is actually a bit subtle and technical. Julia arrays a column major, meaning you move down all of column 1 before starting on column 2. Python and javascript, on the other hand, are row major -- meaning you move across all of row 1 before moving to row 2

What this amounts to is the need to transpose the z argument so that when plotly.js gets it (in javascript land) it will be properly lined up.

This is something that has come up quite a few times in the past few years. I've always been hesitant to overload the call to heatmap on the julia side to insert this transpose, but perhaps it is time.

What do you think @jackparmer ?

NOTE: this would also be required for any trace type/attribute accepting a 2d-array, not just for contour.z

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

jackparmer avatar Jul 31 '21 19:07 jackparmer