使用 pcolormesh 绘制 3D 数据切片

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

我有 2 个 numpy 数组中的数据:一个是 3D 位置列表,另一个是每个位置的标量值。位置数据的顺序相当“奇怪”(见下文)。

3D 位置数据位于数组中:

pos = np.array([[1,1,1],[1,1,2],[1,1,3],[1,2,2],[1,2,1], ...])

pos.shape is (100000,3)

排序不直观(它遵循空间填充曲线)。

我还有想要在每个位置绘制的标量值:

vel = np.array([1,2,1,3,4,...])

vel.shape = (1000000,1)

我的问题是,如何从这些数据中使用 pcolormesh 绘制 xy 切片???我可以用 numpy 提取 xy 平面:

xs = pos[:,:1][:,0]
ys = pos[:,1:2][:,0]

现在我有一堆基本上随机的 x 坐标和 y 坐标,它们不再将 1-1 映射到

vel
数据...:/。我不知道如何首先将这些初始位置映射到我的
vel
数据,以便我可以生成
pcolormesh
:

plt.pcolormesh(X, Y, V)

有人可以帮我分割这些数据,以便所有内容都映射到 xy(和 z)空间中的正确位置吗?

python numpy matplotlib slice
1个回答
0
投票

如果我理解正确,以下方法将适用于您的数据:

  • 找到 z 接近所需 z 的所有索引 (
    np.where()
    )
  • 通过这些索引过滤
    pos
    vel
  • 找到
    pos
  • 中 x 和 y 值的顺序
  • 将此顺序应用于
    vel
    ,并重塑为 2D 数组
  • 通过
    imshow()
    显示二维数组;设置
    vmin
    vmax
    将为不同子图的相同值使用相同的颜色
import matplotlib.pyplot as plt
import numpy as np

# first create some test data

# generate a test grid
N = 100  # size in one dimension
# create a grid of x y and z coordinates
xs, ys, zs = np.meshgrid(range(1, N + 1), range(1, N + 1), range(1, N + 1))
# rearrange them in the shape of the example
pos = np.vstack([xs.ravel(), ys.ravel(), zs.ravel()]).T
# randomly reorder the positions
np.random.shuffle(pos)

# generate a test function for `vel`, depending on pos
# calculate distance to the center of two spheres
center1 = [(N - 1) * 0.2, (N - 1) * 0.6, (N - 1) * 0.5]
radius1 = (N - 1) * 0.3
dist_to_center1 = np.sqrt((pos[:, 0] - center1[0]) ** 2 + (pos[:, 1] - center1[1]) ** 2 + (pos[:, 2] - center1[2]) ** 2)
center2 = [(N - 1) * 0.7, (N - 1) * 0.4, (N - 1) * 0.5]
radius2 = (N - 1) * 0.2
dist_to_center2 = np.sqrt((pos[:, 0] - center2[0]) ** 2 + (pos[:, 1] - center2[1]) ** 2 + (pos[:, 2] - center2[2]) ** 2)
# take union of the two spheres: vel is the minimum of signed distance to the spheres
vel = np.minimum(dist_to_center1 - radius1, dist_to_center2 - radius2)


# display the layers for some z-values
xmin = pos[:, 0].min()
xmax = pos[:, 0].max()
ymin = pos[:, 1].min()
ymax = pos[:, 1].max()
fig, axs = plt.subplots(nrows=2, ncols=4, figsize=(15, 7))
for z_special, ax in zip(range(2, N - 2, N // 8 + 1), axs.flat):
    # indices where the z-value almost equals the desired z value
    filter = np.argwhere((pos[:, 2] > z_special - 0.01) & (pos[:, 2] < z_special + 0.01))[:, 0]
    xy_special = pos[:, :2][filter]
    vel_special = vel[filter]
    # find the order of xy_special on x and y
    order = np.lexsort(([xy_special[:, 0], xy_special[:, 1]]))
    vel_ordered = vel_special[order].reshape(N, -1)
    ax.imshow(vel_ordered, origin='lower', extent=[xmin, xmax, ymin, ymax], aspect='auto',
              cmap='turbo', vmin=-20, vmax=20)
    ax.set_xticks([]) # remove ticks to simplify the plot
    ax.set_yticks([])
    ax.set_title(f"z = {z_special:.3g}")

plt.tight_layout()
plt.show()

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