从网格数据中提取坐标
Extracting coordinates from meshgrid data
我有一个立方体网格,如下图所示。
我想列出每个子立方体的顶点,所以我最终会得到一个嵌套的子立方体列表及其对应的顶点列表。
我最初的尝试是使用生成器,
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
dims = [9,9,9]
spacer = 3
subBoxCoords = np.array([(x, y, z) for x in range(0, dims[0], spacer) for y in range(0, dims[1], spacer) for z in range(0, dims[2], spacer)])
ax.scatter(subBoxCoords[:,0], subBoxCoords[:,1], subBoxCoords[:,2], c='k', marker='o')
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
这确实给了我想要的形状,但坐标的排序方式使得子框的顶点提取不是直截了当的。此外,我想将其推广到任意尺寸的盒子,因此间隔硬编码不是解决方案。
所以,然后我想我会使用 meshgrid
,
nx,ny, nz = (3,3,3)
x = np.linspace(0, 10, nx)
y = np.linspace(0, 10, ny)
z = np.linspace(0, 10, nz)
xv, yv, zv = np.meshgrid(x, y, z, indexing='xy')
ax.scatter(xv, yv, zv, c='g', marker='^')
这似乎是实现我想要的功能的一种非常有效的方法,但我感到很困惑。在meshgrid
中有没有直接访问顶点的方式vertex(x,y,z)
?或者甚至是提取子立方体的直接方法?
在我看来,解决方案非常接近,但我就是无法理解!
meshgrid
可能是您所需要的,但是 meshgrid
返回的数组的形状令人困惑。 Meshgrid returns 三个坐标数组,形状都一样。每个xv, yv, zv
的形状是(len(x), len(y), len(z))
。因此,要提取角 (0, 2, 1)
处的坐标,您可以编写 xv[0, 2, 1], yv[0, 2, 1], zv[0, 2, 1]
为了提取所有子立方体的角坐标,有助于观察到,由于 meshgrid
返回的数组按顺序排序的方式,xv[:-1, :-1, :-1]
returns每个子立方体靠近左下角的 x 坐标。同样,xv[1:, 1:, 1:]
returns 每个子立方体的右上角。其他六个角由切片 :-1
和 1:
的其他六个组合给出(例如,xv[:-1, 1:, :-1]
给出最左上角)。
所以,遍历:-1
和1:
的所有八个组合,得到所有[=25=的八个角的x,y,z坐标三个平行数组的八个平行数组] 子立方体。 (如果您需要您的子立方体角坐标数组具有特定的形状或轴顺序,或者如果您想要使用单个索引而不是三个来指定子立方体,请使用 rollaxis
、swapaxis
和 shape
根据需要。)
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import itertools
nx, ny, nz = (3,3,3)
x = np.linspace(0, 10, nx)
y = np.linspace(0, 10, ny)
z = np.linspace(0, 10, nz)
xv, yv, zv = np.meshgrid(x, y, z, indexing='xy')
slices = slice(None, -1), slice(1, None)
cornerSlices = list(itertools.product(slices, slices, slices))
corners = np.array([(xv[s], yv[s], zv[s]) for s in cornerSlices])
# The shape of `corners` is `(len(cornerSlices), 3, len(x-1), len(y-1), len(z-1)`
# The axes of `corners` represent, in the same order: the corner index; the cartesian
# coordinate axis (the index into [x, y, z]); the x, y, and z indexes of the subcube.
# Plot the first subcube (subcube 0, 0, 0)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
subcube = corners[:, :, 0, 0, 0]
subcubeX = subcube [:, 0]
subcubeY = subcube [:, 1]
subcubeZ = subcube [:, 2]
ax.scatter(subcubeX , subcubeY , subcubeZ , c='g', marker='^')
总是有一种方法可以将索引放入 xv, yv, zv
而不是获取值,因为这些值在 corners
数组中重复了很多次。它将涉及将索引数组切片为 xv, yv, zv
而不是切片数组本身。在深入了解 ndarray 巫毒教之后,我的头已经开始旋转了,所以我将把它留作练习。
我有一个立方体网格,如下图所示。
我想列出每个子立方体的顶点,所以我最终会得到一个嵌套的子立方体列表及其对应的顶点列表。
我最初的尝试是使用生成器,
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
dims = [9,9,9]
spacer = 3
subBoxCoords = np.array([(x, y, z) for x in range(0, dims[0], spacer) for y in range(0, dims[1], spacer) for z in range(0, dims[2], spacer)])
ax.scatter(subBoxCoords[:,0], subBoxCoords[:,1], subBoxCoords[:,2], c='k', marker='o')
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
这确实给了我想要的形状,但坐标的排序方式使得子框的顶点提取不是直截了当的。此外,我想将其推广到任意尺寸的盒子,因此间隔硬编码不是解决方案。
所以,然后我想我会使用 meshgrid
,
nx,ny, nz = (3,3,3)
x = np.linspace(0, 10, nx)
y = np.linspace(0, 10, ny)
z = np.linspace(0, 10, nz)
xv, yv, zv = np.meshgrid(x, y, z, indexing='xy')
ax.scatter(xv, yv, zv, c='g', marker='^')
这似乎是实现我想要的功能的一种非常有效的方法,但我感到很困惑。在meshgrid
中有没有直接访问顶点的方式vertex(x,y,z)
?或者甚至是提取子立方体的直接方法?
在我看来,解决方案非常接近,但我就是无法理解!
meshgrid
可能是您所需要的,但是 meshgrid
返回的数组的形状令人困惑。 Meshgrid returns 三个坐标数组,形状都一样。每个xv, yv, zv
的形状是(len(x), len(y), len(z))
。因此,要提取角 (0, 2, 1)
处的坐标,您可以编写 xv[0, 2, 1], yv[0, 2, 1], zv[0, 2, 1]
为了提取所有子立方体的角坐标,有助于观察到,由于 meshgrid
返回的数组按顺序排序的方式,xv[:-1, :-1, :-1]
returns每个子立方体靠近左下角的 x 坐标。同样,xv[1:, 1:, 1:]
returns 每个子立方体的右上角。其他六个角由切片 :-1
和 1:
的其他六个组合给出(例如,xv[:-1, 1:, :-1]
给出最左上角)。
所以,遍历:-1
和1:
的所有八个组合,得到所有[=25=的八个角的x,y,z坐标三个平行数组的八个平行数组] 子立方体。 (如果您需要您的子立方体角坐标数组具有特定的形状或轴顺序,或者如果您想要使用单个索引而不是三个来指定子立方体,请使用 rollaxis
、swapaxis
和 shape
根据需要。)
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import itertools
nx, ny, nz = (3,3,3)
x = np.linspace(0, 10, nx)
y = np.linspace(0, 10, ny)
z = np.linspace(0, 10, nz)
xv, yv, zv = np.meshgrid(x, y, z, indexing='xy')
slices = slice(None, -1), slice(1, None)
cornerSlices = list(itertools.product(slices, slices, slices))
corners = np.array([(xv[s], yv[s], zv[s]) for s in cornerSlices])
# The shape of `corners` is `(len(cornerSlices), 3, len(x-1), len(y-1), len(z-1)`
# The axes of `corners` represent, in the same order: the corner index; the cartesian
# coordinate axis (the index into [x, y, z]); the x, y, and z indexes of the subcube.
# Plot the first subcube (subcube 0, 0, 0)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
subcube = corners[:, :, 0, 0, 0]
subcubeX = subcube [:, 0]
subcubeY = subcube [:, 1]
subcubeZ = subcube [:, 2]
ax.scatter(subcubeX , subcubeY , subcubeZ , c='g', marker='^')
总是有一种方法可以将索引放入 xv, yv, zv
而不是获取值,因为这些值在 corners
数组中重复了很多次。它将涉及将索引数组切片为 xv, yv, zv
而不是切片数组本身。在深入了解 ndarray 巫毒教之后,我的头已经开始旋转了,所以我将把它留作练习。