Reputation: 11
I could not draw the plane x=y in plotly using python.
My code to generate points on a plane given its normal vector and some point contained in it. What I do is generating two orthonormal vectors that span the plane, and three points in the plane and that set its boundaries. Then I add linear combinations of the vectors to generate points within those boundaries.
As an example, I take the plane x=y:
import numpy as np
import plotly.graph_objects as go
p0 = np.array([0,0,0])
p1 = np.array([0,0,1])
p2 = np.array([1,1,0])
v1 = np.array([0,0,1])
v2 = np.array([1,1,0])/np.sqrt(2)
n1, n2 = v1.dot(p1-p0), v2.dot(p2-p0)
a1, a2 = np.mgrid[0:n1:10*1j,0:n2:10*1j]
a1 = a1.flatten()[np.newaxis,:]
a2 = a2.flatten()[np.newaxis,:]
pts = p0[:,np.newaxis] + a1*v1[:,np.newaxis] + a2*v2[:,np.newaxis]
go.Figure(data=[go.Mesh3d(
x=pts[0],
y=pts[1],
z=pts[2]
)])
This generates the data points I want, but does not draw the Mesh3d, I guess it's because it does not succeed to construct the triangles in the mesh due to the ordering. Probably setting i,j,k might solve the problem, but I wouldn't know how to go about that and even less doing it in general for an arbitrary normal vector. Alternatives to Mesh3d are very welcome, although I do need to use plotly. So my question is how can I reliably construct planes using plotly in Python? Especially if they are perpendicular to some of the axes.
Upvotes: 1
Views: 335
Reputation: 403
There's an issue where Mesh3d doesn't draw the triangles for certain vectors but I've found that if you specify the 2D triangles that you want the graphing algorithm to plot then you can make them show up. To specify the 2D triangles you have to use the parameters i
, j
, and k
. In the documentation it does state "it is preferred that i, j, k are supplied".
Anyway, here's a simple example with three vectors where x=y.
import numpy as np
import plotly.graph_objects as go
fig = go.Figure(data=[go.Mesh3d(
x=[0, 0, 1, 1],
y=[0, 0, 1, 1],
z=[0, 1, 0, 1],
i=[0],
j=[1],
k=[2]
)])
fig.show()
What i
, j
, and k
are doing here is specifying the vectors of the first triangle that should be graphed. i[0]
, j[0]
, k[0]
are the three vectors of the first triangle. If you added a second element to each of these, you'd be specifying the second triangle that should be drawn and so forth.
And here's that demonstrated:
fig = go.Figure(data=[go.Mesh3d(
x=[0, 0, 1, 1],
y=[0, 0, 1, 1],
z=[0, 1, 0, 1],
i=[0, 1],
j=[1, 3],
k=[2, 2]
)])
fig.show()
Further description
The i
, j
, and k
parameters can be confusing so here's a bit of extra detail for anyone who's struggling to understand them. The integers listed in these lists are indexes referencing the vectors of your data. If x
, y
, and z
are of length 4 then you have 4 vectors which are indexed from 0 to 3. So in our example, index 0 is vector [0, 0, 0], index 1 is vector [0, 0, 1], index 2 is vector[1, 1, 0], and index 3 is vector [1, 1, 1]. When specifying the three points or vectors of our triangles, we're referencing the index of the vectors as here described.
Upvotes: 0