总而言之,我想在python中绘制一个通用的3D三角网格。 Matplotlib似乎是理想的候选者,但我会选择任何可以做我要描述的3D渲染。
假设我有一个由X,Y和Z定义的三角形网格,一个点云的三维坐标,每个都是长度为n的向量,而UVW是一个2D mx-3矩阵,其中每一行都是一个三元组点云指数。这个三元组代表一个单独的三角形。换句话说,我在n个点上有三个三角形。在Matlab中,为了生成3D图,我只是这样做:
trisurf(UVW, X, Y, Z)
有没有人有这方面的经验?特别是,mplots trisurf可以用来工作吗?
答案 0 :(得分:5)
根据您的表现需求,mayavi可能最适合这一点 - 根据戴维斯的评论。
但是,matplotlib附带plot_trisurf,您可以完美地传递通用UVW
,X
,Y
,Z
。
使用圆环网格实例:
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()
答案 1 :(得分:1)
答案 2 :(得分:1)
我也在寻找这个问题的解决方案,这次讨论帮助我成功了。以下是它的工作原理:
GBy的评论中已经提供了一个非常类似问题的解决方案作为链接(见上文:Colouring the surface of a sphere with a set of scalar values in matplotlib)
将知识转移到此处的问题会导致创建一个包含振幅的附加数组,并将其分配给“基础ScalarMappable通过set_array
方法”。相应的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)
数组Xcoordinates
,Ycoordinates
,Zcoordinates
包含网格节点的X,Y和Z坐标。用例如,检查它们的形状时Xcoordinates.shape
它应该看起来像(750,)
,其中750是网格节点的数量。矩阵Face
与拉里提出的原始问题中的矩阵UVW相同。它是“一个2D m-x-3矩阵,其中每一行是指向点云的指数的三元组”。如果检查矩阵Face
的形状,它应该类似(1496, 3)
,其中1496是网格中的三角形数,3是一个三角形中的节点数。最后,数组CorticalImage
包含网格中每个节点的幅度,这些是我们想要用于网格颜色的值(而不是Z值)。该数组的形状应该类似于坐标数组的形状,即(750,)
。
重要!!!您可以看到节点数和三角形数不相等。几乎总是如此。另外,通常为节点而不是三角形给出幅度。因此,应计算三角形的幅度,以便在图中获得正确的颜色。这是在colors = np.mean(CorticalImage[Face], axis=1)
行中完成的。
答案 3 :(得分:1)
为了完整起见,我想在这里添加一个mayavi
示例,使用GBy答案中的网格。
import numpy as np
from mayavi import mlab
from tvtk.api import tvtk
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)
mesh = mlab.triangular_mesh(x,y,z, triangles, representation='wireframe',color=(0,0,1) )
mlab.show()
产量: