是否可以对片段中的3D坐标进行排序?

问题描述 投票:0回答:1

我有一组坐标(x,y和z),用于描述人脸的表面。数据类型是pandas数据框,并且数据按z坐标的切片进行排序。我想对数据进行排序,以便将其分隔在网格中。

我是编程新手,所以我没有尝试很多事情。我真的不知道从哪里开始或如何解决这个问题。下面的图片可视化了我正在使用的数据。Picture to visualize data

我无法分享我正在使用的确切数据。我生成了一组数据,这些数据代表我正在使用的数据。数据生成如下所示:

import numpy as np
import matplotlib.pyplot as plt

plt.figure()
ax = plt.axes(projection="3d")
plt.xlabel('X')
plt.ylabel('Y')
ax.set_zlabel('Z')

(x, y) = np.meshgrid(np.arange(-2, 2.1, .1), np.arange(-1, 1.1, .1))
z = 3*x**3-2*y**2

x = x.ravel()
y = y.ravel()
z = z.ravel()

ax.plot3D(x, y, z, linestyle = '', marker ='.')

我希望将数据相对于x和z轴分隔在网格中,以便将数据分隔在不同的数组中。

编辑:我要如何分离数据的可视化:visualization of the result I want

python sorting dataframe 3d
1个回答
0
投票

从图中,您希望网格位于x-z平面中。然后,我们可以从讨论中忽略y值。您没有指定有关网格大小的任何内容。假设是通常,我们可以创建两个数组,分别表示网格块之间的分隔线(对于您的数据,值将有所不同)。请注意,我已将np.inf添加为最后一个元素。

grid_x_lim = np.concatenate([np.arange(-1.5, 1.6, 0.5), [np.inf]])
grid_z_lim = np.concatenate([np.arange(-20, 21, 10), [np.inf]])

[想法是x坐标低于-1.5的任何点都在第一条垂直线的左侧,而z坐标低于-20的任何点都在第一条水平线的下方,依此类推。

对于下面的示例数据(来自您的示例代码)

plt.figure()
ax = plt.axes(projection="3d")
plt.xlabel('X')
plt.ylabel('Y')
ax.set_zlabel('Z')

(x, y) = np.meshgrid(np.arange(-2, 2.1, .1), np.arange(-1, 1.1, .1))
z = 3*x**3-2*y**2

x = x.ravel()
y = y.ravel()
z = z.ravel()

ax.plot3D(x, y, z, linestyle = '', marker ='.')
plt.show()

3D plot of the original data

我们得到(仅在此处绘制x-z坐标)

fig, ax = plt.subplots(1,1)
for x_coord in grid_x_lim[:-1]:  # Plot vertical lines
    ax.axvline(x_coord)
for z_coord in grid_z_lim[:-1]:  # Plot horizontal lines
    ax.axhline(z_coord)
ax.plot(x, z, ".")  # We are only ploting the x-z values
ax.set_xlabel("x")
ax.set_ylabel("z")
plt.show()

plot of the data in the x-z plane with the grid

该图看起来很好,但是我们仍然需要将数据分离到网格中。现在我们使用grid_x_limgrid_z_lim在原始数据中的每个点处找到网格中的索引。

x_idx = np.argmax(x < grid_x_lim[:, np.newaxis], axis=0)
z_idx = np.argmax(z < grid_z_lim[:, np.newaxis], axis=0)

由于您需要线性索引而不是两个索引,因此可以使用

linear_idx = z_idx * grid_z_lim.size + x_idx

linear_idx变量与xyz变量具有相同的尺寸,它指示点落在网格中的块的索引。让我们检查一下它是否起作用。我们可以重复之前的情节,但是我们会用不同的颜色绘制每个块中的点。

fig, ax = plt.subplots(1, 1)
for x_coord in grid_x_lim[:-1]:
    ax.axvline(x_coord)
for z_coord in grid_z_lim[:-1]:
    ax.axhline(z_coord)

colors = ["red", "green", "cyan", "blue", "magenta"]
color_idx = 0
for i in range(grid_x_lim.size * grid_z_lim.size):
    desired_linear_idx = i  # Change this to different values and check the plot
    mask = linear_idx == desired_linear_idx
    if(sum(mask) > 0):
        ax.plot(x[mask], z[mask], ".", color=colors[color_idx])
        color_idx = (color_idx + 1) % len(colors)

ax.set_xlabel("x")
ax.set_ylabel("z")
plt.show()

plot of the data with separated colors

:线性索引从左下角开始,从左到右依次从下到上递增。但是,如果您确实需要从左上角开始调整代码,应该很容易。

© www.soinside.com 2019 - 2024. All rights reserved.