Issue
I am having a tough time drawing the Plotly 3d surface plot. I have a big data frame of 4000 rows and three columns. I did ask questions here and got some answers. When I try them, it takes hours for the code to run yet I see no plot. I want to confirm what I am doing is right. Because I am new to the surface plots.
My code:
import plotly.graph_objects as go
import plotly.graph_objs
import plotly
df =
index x y z
0 10.2 40.5 70.5
1 30.5 30.2 570.5
.
.
4000 100.5 201.5 470.5
df['z']= [df['z'].tolist for x in df.index]
df =
index x y z
0 10.2 40.5 [70.5,570.5,..,470.5]
1 30.5 30.2 [70.5,570.5,..,470.5]
.
.
4000 100.5 201.5 [70.5,570.5,..,470.5]
zdata = [df['z'].tolist()]*len(df)
plotly.offline.plot({"data":[go.Surface(x=df['x'].values,
y=df['y'].values,
z = df['z'].values)],
"layout":plotly.graph_objs.Layout(title='Some data', autosize=False,
width=600, height=600,
scene = dict(xaxis_title='x',
yaxis_title='y',
zaxis_title='z'),
margin=dict(l=10, r=10, b=10, t=10))})
I would be grateful to have somebody clarify me that what I am doing to generate a surface plot is correct?
Solution
Here is a simple / stripped down example of a 3D surface plot to hopefully get you going.
The key message here is: Don't over complicate it. This same logic should be fine on a DataFrame with 4000+ rows. (Granted, it'll plot ~16M data points, so it'll take a bit of time).
The key point to remember is that z
must be a 2d array of the shape [x.shape[0], y.shape[0]]
. Essentially meaning, if x
and y
are of length 10, then z
must be of the shape: [10, 10]
.
As I don't have your complete dataset, I've synthesised the data - hope that's OK for illustration purposes. Additionally, I've stuck with numpy
for simplicity, keeping in mind that a numpy array is essentially a DataFrame column.
Simple example:
import numpy as np
from plotly.offline import plot
n = 10
x = np.arange(n)
y = x
z = np.tile(x**2, [n, 1])
data = [{'x': x,
'y': y,
'z': z,
'type': 'surface'}]
plot({'data': data}, filename='/path/to/graph.html')
Output:
Something a little more fun:
n = 360
x = np.arange(n)
y = x
v = np.tile([np.sin(i*(np.pi/180)) for i in range(n)], [n, 1]).T
z = (v.T[0]*v)
data = [{'x': x,
'y': y,
'z': z,
'type': 'surface'}]
plot({'data': data}, filename='/path/to/graph.html')
You'll note the plotting logic is identical.
Output:
Answered By - S3DEV
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.