Show edges of the mesh in a Mesh3d plot

In the Mesh Cube example (https://plot.ly/python/3d-mesh/#mesh-cube):

import plotly.graph_objects as go
fig = go.Figure(data=[
    go.Mesh3d(
        # 8 vertices of a cube
        x=[0, 0, 1, 1, 0, 0, 1, 1],
        y=[0, 1, 1, 0, 0, 1, 1, 0],
        z=[0, 0, 0, 0, 1, 1, 1, 1],
        colorbar_title='z',
        colorscale=[[0, 'gold'],
                    [0.5, 'mediumturquoise'],
                    [1, 'magenta']],
        # Intensity of each vertex, which will be interpolated and color-coded
        intensity = np.linspace(0, 1, 8, endpoint=True),
        # i, j and k give the vertices of triangles
        i = [7, 0, 0, 0, 4, 4, 6, 6, 4, 0, 3, 2],
        j = [3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3],
        k = [0, 7, 2, 3, 6, 7, 1, 1, 5, 5, 7, 6],
        name='y',
        showscale=True
    )
])

fig.show()

How can the edges of the individual triangles be outlined?

Hi @sibowi, I don’t think this is possible at the moment. You can add lines separately by adapting the (slightly outdated) example from https://plot.ly/python/v3/3d-wireframe-plots/

@sibowi

Usually a Mesh3d is defined by a surface triangulation, that consists in two arrays, one that defines the vertices (3d points), of shape (n, 3), and another that define the triangles, of shape (m, 3). A triangle is defined by a list/tuple of 3 ints representing the indices of the rows in the vertex array that contain triangle vertices
To get the vertex array and triangle array from the code you posted perform the following operations:

i = [7, 0, 0, 0, 4, 4, 6, 6, 4, 0, 3, 2]
j = [3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3]
k = [0, 7, 2, 3, 6, 7, 1, 1, 5, 5, 7, 6]

triangles = np.vstack((i,j,k)).T

x = [0, 0, 1, 1, 0, 0, 1, 1]
y = [0, 1, 1, 0, 0, 1, 1, 0]
z = [0, 0, 0, 0, 1, 1, 1, 1]
vertices = np.vstack((x,y,z)).T
tri_points = vertices[triangles]

#extract the lists of x, y, z coordinates of the triangle vertices and connect them by a line
Xe = []
Ye = []
Ze = []
for T in tri_points:
    Xe.extend([T[k%3][0] for k in range(4)]+[ None])
    Ye.extend([T[k%3][1] for k in range(4)]+[ None])
    Ze.extend([T[k%3][2] for k in range(4)]+[ None])
       
#define the trace for triangle sides
lines = go.Scatter3d(
                   x=Xe,
                   y=Ye,
                   z=Ze,
                   mode='lines',
                   name='',
                   line=dict(color= 'rgb(70,70,70)', width=1))  

To understand the definition of tri_points and how the lists Xe, Ye, Ze are defined, just print its shape and the first element, tri_points[0].

Here is a more general example of mesh3d defined from an a ply file (a file format that contains a mesh, i.e. a triangulated surface):
[https://plot.ly/~empet/14749] (https://plot.ly/~empet/14749)

5 Likes

@empet

This was exactly what I was looking for. The notebook is very well written, and made it easy to understand the method.

Thank you very much!

Might be faster with numpy if you have a lot of points.

tri_points = np.array([
    vertices[i] for i in triangles.reshape(-1)
])
Xe, Ye, Ze = tri_points.T

@jonnymaserati Without None after each triangle, you’ll get a tangled plot. Just try your solution and post here the resulting mesh. :slight_smile: