Black Lives Matter. Please consider donating to Black Girls Code today.

Add lines to 3D surface

I am a newbie to Plotly. Is there a way to draw data lines on top of a 3D surface graph. I have managed to draw the graph but cannot figure out how to add lines to it (I have attached the target image). Kindly help. This is my code and dataset.



#!/usr/bin/env python
#import plotly.graph_objects as go
from plotly.offline import iplot, init_notebook_mode
init_notebook_mode()

import pandas as pd
import copy

z_data = pd.read_csv(‘https://raw.githubusercontent.com/rogomichael/plotpl/master/trial.csv’)
z2_data = pd.read_csv(‘https://raw.githubusercontent.com/rogomichael/plotpl/master/set2.csv’)
#surfacecolor = copy.deepcopy(z2_data)
#surfacecolor[2][2] = 0
fig = go.Figure(data=[
go.Surface(
x = [-5,-4,-3,-2,-1,0,1,2,3,4,5],
y = [-4,-3,-2,-1,0,1,2,3,4,5,6],
z=z2_data,
colorscale = ‘reds’,
opacity = 1,
#colorscale=‘Electric’,
#surfacecolor=surfacecolor,
showscale=False),
go.Surface(
x = [-5,-4,-3,-2,-1,0,1,2,3,4,5],
y = [-4,-3,-2,-1,0,1,2,3,4,5,6],
z=z_data.values,
#colorscale=‘aggrnyl’,
colorscale = ‘greens’,
opacity = 1,
#colorscale = [[0, ‘green’], [-0.5, ‘red’], [-1.0, ‘rgb(0, 0, 255)’]],
showscale=False)])

fig.update_layout(title=‘ch3_ci’,
scene ={“xaxis”:{“title”: “g/NAC [Angs]”},
“yaxis”:{“title”: “h/GD [Angs]”},
“zaxis”:{“title”: “energy/eV”}},
autosize=True,
width=950, height=950,
margin=dict(l=65, r=50, b=65, t=120))

#fig.show()
iplot(fig, image=‘svg’, filename=‘ch3_plot.svg’)

Hi @rogomichael,

The Plotly surfaces reveal very well their geometry that’s why I wouldn’t draw wireframes to get them looking like matlab surfaces . There is no trace designed specially for wireframes, but we could define the transversal lines onto the surface as Scatter3d lines:

import numpy as np
import plotly.graph_objects as go

x = np.linspace(-1,1, 50)
y = np.linspace(-1,3, 100)
x, y = np.meshgrid(x,y)

z = x**3-3*y*x+1  # the surface eqn

fig = go.Figure()
fig.add_surface(x=x, y=y, z=z, colorscale='Reds_r', colorbar_thickness=25, colorbar_len=0.75);

X = np.linspace(-1,1, 6)
Y = np.linspace(-1, 3, 12)
#Define the first family of coordinate lines
X, Y = np.meshgrid(X,Y)
Z = X**3-3*Y*X+1
line_marker = dict(color='#101010', width=4)
for xx, yy, zz in zip(X, Y, Z+0.03):
    fig.add_scatter3d(x=xx, y=yy, z=zz, mode='lines', line=line_marker, name='')
#Define the second family of coordinate lines
Y, X = np.meshgrid(Y, X)
Z = X**3-3*Y*X+1
line_marker = dict(color='#101010', width=4)
for xx, yy, zz in zip(X, Y, Z+0.03):
    fig.add_scatter3d(x=xx, y=yy, z=zz, mode='lines', line=line_marker, name='')    
fig.update_layout(width=700, height=700, showlegend=False)
fig.show()

Thank you @empet for your answer. Can this be done using z data points from my values or I have to figure out a z equation for this to work in my case. Sorry I am very green in this area. Kindly help .

@rogomichael You can use your z-data but, in both cases (surface and lines) z must have the same shape as x, y
in the meshgrid.

@empet, I sat down and did a little bit of thinking to produce the result I wanted. Thanks for your suggestions. One more question, how do I shift/push the z values away from the margin/tickslines and how can I do the same with the label without changing the camera because I am interested in the intersecting point view?. I have tried all tricks but none worked
trial_view

@rogomichael

To change the surface position with respect to the three coordinate planes I suggest to enlarge the `zaxis_range’
from, let us say, [a, b] to [a-h, b] for some h you’ll choose by trial and error and a similar update for the axis that now is horizontal.