Matplotlib 3D绘图zorder问题
我有一个图,里面有一个蓝色的表面(用 plot_surface
绘制)和一个红色的球体(用 scatter
绘制)。蓝色表面的层级设置为0,而红色球体的层级设置为1(其实不设置层级值也能得到一样的效果)。
你可以看到红色球体在蓝色表面的左边:
当我旋转这个图的时候,你会发现红色球体开始在蓝色表面后面消失,尽管它实际上是在前面:
直到红色球体完全消失:
奇怪的是,在某些角度下,红色球体又重新出现并且可见,比如这个角度:
这是怎么回事呢?我看过一些关于绘图和层级相关的问题,但没有见过像这样一个物体明显在另一个物体的前面或后面,却在大多数视角下显示不正确的情况。
如果我把蓝色表面设置为透明,你就能在下面的图中看到红色球体在表面后面消失(所以看起来绘图库确实认为它在表面后面)。
2 个回答
2
在Matplotlib 1.5.3版本(2016年)中,这个问题依然存在。@tacaswell(他是Matplotlib开发的共同负责人)推荐的替代方案是使用Mayavi来处理3D绘图。Mayavi在Python绘图库中比较特别,因为它不像其他很多项目(比如Pandas、Seaborn、ggplot)那样使用Matplotlib作为后端。
我在OSX上使用Homebrew和pip安装Mayavi时,过程非常简单。
#/bin/bash
# vtk is a mayavi requirement
brew install vtk
pip install mayavi
# Port your matplotlib code to mayavi
# Profit...
6
从Matplotlib 3.5.0版本开始,增加了一个设置,可以解决这个问题。这个设置叫做computed_zorder。
举个例子:
ax = plt.axes(projection='3d',computed_zorder=False)
ax.plot_surface(X, Y, Z,zorder=1)
ax.plot_surface(U, V, W,zorder=2)
具有最高zorder值的元素会显示在最上面。
一些默认的zorder值可以在这里找到:
艺术家 | zorder |
---|---|
图像(AxesImage, FigureImage, BboxImage) | 0 |
补丁,补丁集合 | 1 |
线(Line2D, LineCollection,包括小刻度和网格线) | 2 |
主要刻度 | 2.01 |
文本(包括坐标轴标签和标题) | 3 |
图例 | 5 |