我正在用matplotlib准备3d图,我对多个数据集有一个非常奇怪的行为。我有两个数据集,基本上描述了3D中的两个壳:一个内壳和一个 shell 。在3D中绘制它们:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(outer_z[:n], outer_x[:n], outer_y[:n], c='black', marker='.', lw=0)
ax.scatter(inner_z[:n], inner_x[:n], inner_y[:n], c='red', marker='.', lw=0)
ax.set_xlabel("Z")
ax.set_ylabel("X")
ax.set_zlabel("Y")
ax.set_xlim([-5,5])
ax.set_ylim([5,-5])
ax.set_zlim([-5,5])
(the轴的顺序仅用于透视目的)。但是,当我保存图形时,我不会得到两个壳:
我得到一层在另一层之上,明显在后面的点出现在前面。你可以在图片上看到, shell 的一些点应该在内壳的后面,但却绘制在内壳的前面。这真的很烦人,因为它不追求“3d中的情节”的目的。有没有人知道为什么会发生这种情况,以及如何解决?
2条答案
按热度按时间oxiaedzo1#
我知道这不能解决你的问题,但也许能解释为什么它会这样。
这与Matplotlib实际上没有3D引擎有关。Mplot 3D获取您的点并将其投影到2D图上(对于每个对象),然后Matplotlib一次绘制一个对象; Matplotlib是一个2D绘图框架,Mplot 3D是一种小技巧,可以让一些3D功能工作,而无需为Matplotlib编写一个完整的3D引擎。
这意味着你绘制不同图的顺序(在这种情况下是红点和黑点)很重要,如果你在红点之后绘制黑点,它们将出现在红点之前,无论它们的位置如何。
让我用另一个例子来说明这一点。
这给出:x1c 0d1x
但从俯视图中你可以看到这条线在螺旋线内部:
但是,如果交换绘制这些线的顺序:
然后,您会看到在螺旋线之后绘制的直线:
最终,这意味着您必须手动确定哪些点将位于其他点的前面。然后,您可以使用zorder参数来确定哪些对象将位于其他对象的前面。但是你必须为每个透视图(Angular ,高度)做这件事。在这种情况下,您可能必须将内部线分解为“infront_of_helix”和“behind_helix”部分,然后分别在螺旋的前面和后面绘制它们。
我希望有人沿着对这件事做更多的阐述,因为我自己对这个主题很感兴趣。我知道mplot 3d有一些基本的方法来确保前面的点首先显示,我相信,当它使用着色算法时,但我不完全确定。
epfja78i2#
非常感谢你的解释:)我想它确实可能是这样的。但是我忘了在我的问题中说,无论ax.scatter命令的顺序如何,都会发生同样的事情,这很奇怪。在阅读您的答案之前,我发现ax.plot命令不会发生这种情况。因此,我替换了:
由
我得到了下面的图片:
这对我很有效然而,我知道,如果我改变视角,我会让红色 shell 出现在黑色 shell 的顶部。我后来发现的一个问题是.plot函数没有vmin和vmax参数(和.scatter一样),这使得它更难将颜色定义为从vmin和vmax开始的渐变。