在3D numpy矩阵中绘制给定值的表面轮廓

时间:2019-03-22 02:59:49

标签: python numpy matplotlib

我有三个与xyz坐标空间相对应的3D网格矩阵(XYZ)。

我还有一个3D numpy矩阵A,其中A[i,j,k]包含一个与(x,y,z)x=X[i,j,k]和{ {1}}。浮点值在y=Y[i,j,k]内是连续的(即z=Z[i,j,k]的相邻元素之间的值变化通常很小)。

是否有一种方法可以使用Matplotlib或任何其他基于Python的图形包在A中绘制与给定float值相对应的表面?例如,如果给定值A,那么我有兴趣在A(正负公差)出现的任何地方获取矩阵2.34的绘制轮廓表面吗?

到目前为止,我已经能够恢复A中所有在目标值允许范围内的值的xyz坐标,然后使用this制作3D散点图(下面的代码) 。也许还有一种方法可以从这些点绘制表面?

2.34

我也尝试过A,但这使我的情节联系不佳。我猜想数组中值的顺序可能会影响到这种情况,在这种情况下,有一个程序包可以对点进行随机排序(例如,通过最小化表面积或类似方法)来进行某种3D内插表面绘图?)

我感兴趣的对象大致是球形的(即每个(x,y)两个z)。我似乎找不到任何有人在封闭的3D曲面上进行三角剖分的有效示例,但也许我没有在正确的位置寻找。

1 个答案:

答案 0 :(得分:1)

经过大量的研究,我认为我已经找到了一个可行的解决方案(至少对于球体-当我尝试球体变形时,将更新我的答案)。非常感谢能帮助我思考正确道路的评论。我基本上是使用ConvexHull进行三角剖分的scipy.spatial

from matplotlib.tri import Triangulation
from scipy.spatial import ConvexHull

def clean (A, t, dt):
    # function for making A binary for t+-dt
    # t is the target value I want in the matrix A with tolerance dt
    new_A = np.copy(A)
    new_A[np.logical_and(new_A > t-dt, new_A < t+dt)] = -1
    new_A[new_A != -1] = 0
    new_A[new_A == -1] = 1
    return (new_A)

def get_surface (X, Y, Z, new_A):
    x_vals = []
    y_vals = []
    z_vals = []

    # Retrieve (x,y,z) coordinates of surface
    for i in range(new_A.shape[0]):
        for j in range(new_A.shape[1]):
            for k in range(new_A.shape[2]):
                if new_A[i,j,k] == 1.0:
                    x_vals.append(X[i,j,k])
                    y_vals.append(Y[i,j,k])
                    z_vals.append(Z[i,j,k])

    return (np.array(x_vals), np.array(y_vals), np.array(z_vals))

cleaned_A = clean (A, t=2.5, dt=0.001)
x_f, y_f, z_f = get_surface (X, Y, Z, cleaned_A )

Xs = np.vstack((x_f, y_f, z_f)).T
hull = ConvexHull(Xs)
x, y, z = Xs.T

tri = Triangulation(x, y, triangles=hull.simplices)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d', aspect='equal')
ax.plot_trisurf(tri, z, color='g', alpha=0.1)