在mplot3d中排序数据以绘图

3 投票
1 回答
957 浏览
提问于 2025-04-16 07:18

我一直在使用mplot3d(这是matplotlib的一部分)来做一些3D绘图,效果很好。不过,我遇到了一个新问题。

mplot3d希望数据按照特定的方式排序,才能绘制出线框图。例如,它需要的数据格式大概是这样的:

x = array([[1, 2, 3],
          [1, 2, 3],
          [1, 2, 3]])

y = array([[1, 1, 1],
          [2, 2, 2],
          [3, 3, 3])

其中z也是一个相同大小的数组,里面的数据对应于每个空间位置。

可惜的是,我的数据格式并不是这样——每隔一行就反转一次,因为数据是通过扫描栅格模式收集的。

所以我现在的数据看起来更像这样:

x = array([[1, 2, 3],
          [3, 2, 1],
          [1, 2, 3]])

我目前的做法是一个很笨的方法,就是“用一个循环,然后检查你是不是在奇数行”,这样从旧数组中构建一个新数组,但我希望能有更优雅的解决办法。棘手的地方在于,我必须以和X、Y相同的方式重新排列Z数组,以确保每个点对应的数据在空间中是正确的。

理想情况下,我希望能有一个强大且专门设计来排序包含任意随机位置点的二维数组的方法,但即使是更符合Python风格的做法也会让我很感激。如果我能让它更强大,不依赖于这种特定的栅格扫描模式,那长远来看可能会省去我不少麻烦。

1 个回答

2

如果我理解得没错,你想做的就是这个:x[1::2, :] = x[1::2, ::-1]

不过这里有一些小问题……如果你不先复制一份x,结果可能不会像你预期的那样,因为numpy的广播机制会影响结果。

尽管如此,使用基本的索引操作其实还是挺简单的:

import numpy as np
x = np.array([[1,2,3],[3,2,1],[1,2,3],[3,2,1],[1,2,3]])
x_rev = x.copy()
x_rev[1::2, :] = x[1::2, ::-1]

这会把这个(x):

array([[1, 2, 3],
       [3, 2, 1],
       [1, 2, 3],
       [3, 2, 1],
       [1, 2, 3]])

转换成这个(x_rev):

array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

如果你对Python中的切片不太熟悉,x[1::2]的意思是从第二个元素开始,每隔一个选一个,也就是选择每隔一项的元素。这里的1是起始索引,2是步长。相对而言,x[::-1]则是指定步长为-1,也就是将数组反转。在这个例子中,我们只是对特定的轴应用这些切片,所以可以选择并反转每隔一行的内容,从第二行开始。

撰写回答