To make a long story short, I'd like to plot a generic 3D triangle mesh in python. Matplotlib seems to be the ideal candidate, but I'd go with any 3D rendering that can do what I'm about to describe.
Suppose I have a triangle mesh defined by X, Y, and Z, the 3D coordinates of a point cloud, each a vector of length n, and UVW, a 2D m-x-3 matrix in which each row is a triplet of indices into the point cloud. This triplet represents an individual triangle. In other words, I have m triangles over n points. In Matlab, to generated a 3D plot, I just do:
trisurf(UVW, X, Y, Z)
Does anyone have any experience with this? In particular, can mplots trisurf be shoehorned to work?
Depending on your performance needs, mayavi is likely to be best suited for this - as per Davis comment.
However, matplotlib comes with plot_trisurf to which you can perfectly pass generic
UVW
,X
,Y
,Z
as you describe.Exemple with a torus mesh:
Plotly has an open-source trisurf Python implementation that is closer to MATLAB's trisurf().
Python code and examples here:
https://plot.ly/python/tri-surf/
I was also looking for a solution to this problem and this discussion helped me to succeed. Here is how it works:
A solution to very similar problem was already given as a link here in the comment from GBy (see above: Colouring the surface of a sphere with a set of scalar values in matplotlib)
Transfering the knowledge to the problem here it results in creating an additional array containing the amplitudes and assigning it to the "underlying ScalarMappable through
set_array
method". The corresponding python code looks like this:The arrays
Xcoordinates
,Ycoordinates
,Zcoordinates
contain the X, Y and Z coordinates of the mesh nodes. When checking their shape with e.g.Xcoordinates.shape
it should look like this(750,)
, where 750 is the number of mesh nodes. The matrixFace
is the same as the matrix UVW in the original question asked by Larry. It is "a 2D m-x-3 matrix in which each row is a triplet of indices into the point cloud". If you check the shape of the matrixFace
it should be something like(1496, 3)
, where 1496 is the number of triangles in the mesh and 3 is the number of nodes in one triangle. Finally, the arrayCorticalImage
contains the amplitudes for every node in the mesh and these are the values, which we want to use for the colors of the mesh (and not the Z values). The shape of that array should be like the shapes of the coordinates arrays, i.e.(750,)
.IMPORTANT!!! You can see that the number of nodes and the number of triangles are not equal. This is almost always the case. Additionally, the amplitudes are usually given for the nodes and not for the triangles. Consequently, the amplitudes should be calculated for the triangles in order to get the right colors in the plot. This is done in the line
colors = np.mean(CorticalImage[Face], axis=1)
.Thought for completeness sake I would add a
mayavi
example here, using the mesh from GBy's answer.Yielding: