26

好的,所以我觉得应该有一种简单的方法来使用 matplotlib 创建一个 3 维散点图。我有一个 3D numpy 数组 ( dset),其中 0 是我不想要的点,而 1 是我想要的地方,基本上现在要绘制它,我必须for:像这样逐步完成三个循环:

for i in range(30):
    for x in range(60):
        for y in range(60):
            if dset[i, x, y] == 1:
                ax.scatter(x, y, -i, zdir='z', c= 'red')

关于如何更有效地完成此任务的任何建议?任何想法将不胜感激。

4

2 回答 2

31

如果您有dset类似的情况,并且只想获取1值,则可以使用nonzero,它“返回数组元组,每个维度一个a,包含该维度中非零元素的索引。”。

例如,我们可以制作一个简单的 3d 数组:

>>> import numpy
>>> numpy.random.seed(29)
>>> d = numpy.random.randint(0, 2, size=(3,3,3))
>>> d
array([[[1, 1, 0],
        [1, 0, 0],
        [0, 1, 1]],

       [[0, 1, 1],
        [1, 0, 0],
        [0, 1, 1]],

       [[1, 1, 0],
        [0, 1, 0],
        [0, 0, 1]]])

并找到非零元素所在的位置:

>>> d.nonzero()
(array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2]), array([0, 0, 1, 2, 2, 0, 0, 1, 2, 2, 0, 0, 1, 2]), array([0, 1, 0, 1, 2, 1, 2, 0, 1, 2, 0, 1, 1, 2]))
>>> z,x,y = d.nonzero()

如果我们想要一个更复杂的切割,我们可以做一些类似(d > 3.4).nonzero()的事情,因为 True 有一个整数值 1 并且计数为非零。

最后,我们绘制:

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, -z, zdir='z', c= 'red')
plt.savefig("demo.png")

给予

演示 3d 图像

于 2012-09-13T21:08:31.783 回答
1

如果您想避免使用该nonzero选项(例如,如果您有一个 3D numpy 数组,其值应该是数据点的颜色值),您可以做您所做的,但使用ndenumerate.

您的示例可能变为:

for index, x in np.ndenumerate(dset):
    if x == 1:
        ax.scatter(*index, c = 'red')

我想重点是您不需要嵌套 for 循环来遍历多维 numpy 数组。

于 2019-11-16T01:59:35.467 回答