pythonplotly

Plotly wireframe running along both directions


I wanted to create a wireframe surface in plotly. However the following code only runs the wires along one axis. How do I convert these parallel wires into a mesh?

import numpy as np
import plotly.graph_objects as go
import plotly.io as pio

x = np.linspace(-5, 5, 20)
y = np.linspace(-5, 5, 20)
x, y = np.meshgrid(x, y)

a = 1
b = 1
z = (x**2 / a**2) - (y**2 / b**2)


# Add lines
lines = []
line_marker = dict(color='#000000', width=4)
for i, j, k in zip(x, y, z):
    lines.append(go.Scatter3d(x=i, y=j, z=k, mode='lines', line=line_marker))


fig = go.Figure(data=lines)

pio.templates["Mathematica"] = go.layout.Template()


# Update layout
fig.update_layout(
    title='3D Hyperbolic Paraboloid',
    scene=dict(
        xaxis_title='X-axis',
        yaxis_title='Y-axis',
        zaxis_title='Z-axis'
    ),
    template = 'Mathematica',

)

fig.show()

enter image description here


Solution

  • Update: An easier way would be to just use the contours. In this case one simply needs to change trace2.

    trace2 = go.Surface(z=z, x=x, y=y, contours = {
            "x": {"show": True, "start":-5, "end": 5, "size": 1, "color":"black"},
            "y": {"show": True, "start": -5, "end": 5, "size": 1}
        })
    

    After that trace1 is redundant.

    Original Answer

    Nevermind, I managed it, although a slicker answer would be nice.

    The problem stems from the meshgrid because the iteration of the grid provides a changing value of x for a constant y. Taking a transpose of the x, y, and z generated by the mesh, one can plot the perpendicular lines:

    import numpy as np
    import plotly.graph_objects as go
    import plotly.io as pio
    
    
    x = np.linspace(-5, 5, 10)
    y = np.linspace(-5, 5, 10)
    x, y = np.meshgrid(x, y)
    
    a = 1
    b = 1
    z = (x**2 / a**2) - (y**2 / b**2)
    
    
    # Add lines
    lines = []
    line_marker = dict(color='#000000', width=4)
    for i, j, k in zip(x, y, z):
        lines.append(go.Scatter3d(x=i, y=j, z=k, mode='lines', line=line_marker))
    for i, j, k in zip(x.T, y.T, z.T):
        lines.append(go.Scatter3d(x=i, y=j, z=k, mode='lines', line=line_marker))
    
    
    trace1 = lines
    trace2 = go.Surface(z=z, x=x, y=y)
    
    fig = go.Figure(lines)
    fig.add_trace(trace2)
    
    pio.templates["Mathematica"] = go.layout.Template()
    
    
    # Update layout
    fig.update_layout(
        title='3D Hyperbolic Paraboloid',
        scene=dict(
            xaxis_title='X-axis',
            yaxis_title='Y-axis',
            zaxis_title='Z-axis'
        ),
        template = 'Mathematica',    
    )    
    fig.show()
    

    enter image description here