Announcing Dash Bio 1.0.0 🎉 : a one-stop-shop for bioinformatics and drug development visualizations.

Axes mixed when plotting a 3D surface

Consider the following snippet:

fig = go.Figure(
    data=[
        go.Surface(
            x=list(range(1,20)),
            y=list(range(1,10)),
            z=np.random.random(size=(20,10))
        )
    ]
)
fig.update_layout(
    autosize=False,
    width=1200,
    height=800,
)

which yields:

Problem: Note that not all the x-axis range is plotted! Following snippet tries to fix it:

fig = go.Figure(
    data=[
        go.Surface(
            x=list(range(1,20)),
            y=list(range(1,10)),
            z=np.random.random(size=(20,10))
        )
    ]
)
fig.update_layout(
    autosize=False,
    width=1200,
    height=800,
    scene=dict(  # Adding explicit x/y ranges
            xaxis = dict(range=[0,20]),
            yaxis = dict(range=[0,10]),
        ),
)

yields:

Problem: Better. But still, the Z-data is not shown for the 10-20 range of the x-axis. Final attempt:

fig = go.Figure(
    data=[
        go.Surface(
            x=list(range(1,20)),
            y=list(range(1,10)),
            z=np.random.random(size=(10,20))  # note the change in the order of the arguments of the size
        )
    ]
)
fig.update_layout(
    autosize=False,
    width=1200,
    height=800,
    scene=dict(
            xaxis = dict(range=[0,20]),
            yaxis = dict(range=[0,10]),
        ),
)

yields the expected result:

Question: What am I missing here? This is a little counterintuitive.

@drorata
No, the axes aren’t mixed, but the definition of your z is wrong. z regarded as an array must have len(y) rows and len(x) columns.
Hence define z=np.random.random(size=(10,20)) and you’ll get the right surface and axis ticklabels
Usually a surface of equation, z=f(x, y), x in [a, b], y in [c,d], is defined as follows:

a, b =[-1, 1]
c, d =[-1, 2]
x=np.linspace(a, b, 100)
y=np.linspace(c, d, 150)
X,Y=np.meshgrid(x,y)
z=-X**3+3*Y*X**2-1
print(z.shape)

fig = go.Figure(go.Surface(
            x=x,
            y=y,
            z=z
        )
)
fig.update_layout(
    width=800,
    height=800,
)

Similarly is defined a surface in matplotlib 3D surface (colormap) — Matplotlib 3.5.1 documentation, bokeh etc