Matplotlib类似于matlab的trisu

2024-05-12 21:56:05 发布

您现在位置:Python中文网/ 问答频道 /正文

长话短说,我想用python绘制一个通用的3D三角形网格。Matplotlib似乎是理想的候选对象,但是我会使用任何可以完成我将要描述的任务的三维渲染。

假设我有一个由X,Y,Z定义的三角形网格,一个点云的三维坐标,每一个长度为n的向量,和一个2dm-X-3矩阵,其中每一行是点云的三个索引。这个三元组代表一个单独的三角形。换句话说,n点上有m个三角形。在Matlab中,要生成3D图,我只需要:

trisurf(UVW, X, Y, Z)

有人有这方面的经验吗?特别是,mplots-trisurf能被强制工作吗?


Tags: 对象网格定义matplotlib绘制代表矩阵向量
3条回答

根据您的性能需求,mayavi可能最适合这样做-根据Davis的评论。

然而,matplotlib附带了plot_trisurf,您可以完美地将泛型UVWXYZ传递给它。

例如,使用圆环网格:

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import matplotlib.tri as mtri

R = 1.
r = 0.8
n = 50
m = 50

def torus_triangles(n, m):
    """ Returns triangles to mesh a (n, m) torus """
    tri = []
    for i in range(n):
        for j in range(m):
            a = i + j*(n)
            b = ((i+1) % n) + j*n
            d = i + ((j+1) % m) * n
            c = ((i+1) % n) + ((j+1) % m) * n
            tri += [[a, b, d], [b, c, d]]
    return np.array(tri, dtype=np.int32)

theta0 = np.linspace(0, (2*np.pi), n, endpoint=False)
phi0 = np.linspace(0, (2*np.pi), m, endpoint=False)
theta, phi = np.meshgrid(theta0, phi0)

x = (R + r * np.sin(phi)) * np.cos(theta)
y = (R + r * np.sin(phi)) * np.sin(theta)
z = r * np.cos(phi)

triangles = torus_triangles(n , m)
triang = mtri.Triangulation(x.ravel(), y.ravel(), triangles)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(triang, z.ravel(), lw=0.2, edgecolor="black", color="grey",
                alpha=0.5)

plt.show()

enter image description here

我也在寻找解决这个问题的办法,这次讨论帮助我取得了成功。它的工作原理如下:

  1. 一个非常类似的问题的解决方案已经在GBy的注释中作为链接给出了(见上面的:Colouring the surface of a sphere with a set of scalar values in matplotlib

  2. 将知识转移到这里的问题上,会导致创建一个包含振幅的附加数组,并将其分配给“通过set_array方法实现的底层ScalarMappable”。相应的python代码如下所示:

    from mpl_toolkits.mplot3d import Axes3D
    from matplotlib import cm
    from matplotlib import pyplot as plt
    import numpy as np
    
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    colors = np.mean(CorticalImage[Face], axis=1)
    collec = ax.plot_trisurf(Xcoordinates, Ycoordinates, Zcoordinates, triangles=Face, cmap=cm.jet, linewidth=0.2)
    collec.set_array(colors)
    collec.autoscale()
    ax.view_init(30, 0)
    cbar = fig.colorbar(collec)
    

数组XcoordinatesYcoordinatesZcoordinates包含网格节点的X、Y和Z坐标。当用Xcoordinates.shape检查它们的形状时,应该像这样(750,),其中750是网格节点的数量。矩阵Face与Larry提出的原始问题中的矩阵UVW相同。它是“一个2dm-x-3矩阵,其中每一行是点云的三个索引集”。如果您检查矩阵的形状Face,它应该类似于(1496, 3),其中1496是网格中的三角形数,3是一个三角形中的节点数。最后,数组CorticalImage包含网格中每个节点的振幅,这些是我们要用于网格颜色(而不是Z值)的值。数组的形状应该与坐标数组的形状类似,即(750,)

重要!!!可以看到节点数和三角形数不相等。几乎总是这样。此外,振幅通常是为节点而不是为三角形给定的。因此,应计算三角形的振幅,以便在绘图中获得正确的颜色。这是在colors = np.mean(CorticalImage[Face], axis=1)行中完成的。

Plotly有一个开源的trisurf Python实现,它更接近于MATLAB的trisurf()。

这里是Python代码和示例:

https://plot.ly/python/tri-surf/

python trisurf

相关问题 更多 >