Bring Drag & Drop to Dash with Dashboard Engine. 💫 Learn how at our next webinar!

Vectorial planes

Hi guys, I need to plot Vectorial Planes (more specifically a geological plane). I was thinking something similar to 3D Cones. But changing the shape of a cone for a plane.

Any ideas?

Thanks for all!

@luquezsantiago

Could you please give a link to a geological plane to see what it is in order to suggest the most suitable plotly chart type to draw it?

Hi, thanks for the fast answer.
What I need is to plot lots of points (x,y,z), but every point has a vectorial data. So I was thinking something similar to the cones, but instead of ploting a cone, ploting only a plane (the blue without the red arrow).

In the figure below, you can see all the points where instead of a point should be planes.

image

Thanks for all!

@luquezsantiago

A plane is defined and plotted as a surface:

import numpy as np
import plotly.graph_objects as go


# plane defined by a point  M and its normal v

def get_plane(M, v, a =5):
    # derive the parametric equations of a plane through M and of normal vector v
    I = np.nonzero(v)[0] # I contains the index of the nonzero coordinates of v
    if len(I) == 0:
        raise ValueError('v is the null vector and cannot be the normal vec')


    # The plane equation is v[0](x-xM)+v[1](y-yM)+v[2](z-zM)=0
    # Depending on which coordinate of v is non-zero, we derive the plane parameterization:

    D = np.dot(M, v)
    if I[0] == 0:
        y = np.linspace(-a, a, 100) 
        y, z = np.meshgrid(y, y)
        x = - (v[1]*y + v[2]*z) / v[0] + D
        return x, y, z
    elif I[0] == 1:
        x = np.linspace(-a, a, 100) 
        x, z = np.meshgrid(x, x)
        y = -(v[0]*x + v[2]*z) / v[1] + D
        return x, y, z
    else:
        x = np.linspace(-a, a, 100) 
        x, y = np.meshgrid(x, x)
        z = -(v[0]*x + v[1]*y) / v[2] + D
        return x, y, z



#Example
M = np.array([-1, 2., 1])
v = np.array([1, -3., 2])
centroid = np.array([2.19713507, 2.31639408, 2.29542484], float)

xp, yp, zp  = get_plane(M, v)

fig = go.Figure(go.Surface(x=xp, y=yp, z=zp, 
                           colorscale = [[0,  '#ADD8E6'], 
                                         [1, '#ADD8E6']],
                           showscale=False))


fig.update_layout(title= '',  width=600, height=600)
fig.show()

The following update removes the scene:

fig.update_scenes(xaxis_visible=False, 
                  yaxis_visible=False, 
                  zaxis_visible=False) 

The default projection for plotting 3d geometrc elements is the perspective projection (the two examples above).
To set the orthographic projection, perform this update:

fig.update_scenes(camera_projection_type = "orthographic")

To get ore information on scene attributes, print:

help(go.layout.Scene)
2 Likes

Wow! thanks so much for all the help! I will try with your code and let you know how is going!

thank for all!!!

Thanks for all the help. Unfortunately I couldn’t plot all the planes. The problem I have is that with ‘‘go.Surface ()’’ I can make several surfaces, but I have over 1,000s to plot. Is there a way to plot many surfaces using go.Surface and a Dataframe?

Thanks for all, again!

@luquezsantiago

What should contain the dataframe? The data for a small or a big number of surfaces can be given in different forms. plotly.py does not restrict how your initial data are given. From data provided by a dataframe you must derive the x, y, z - meshgrids to define the plotly surfaces.