在matplotlib中显示Surface前面的轮廓

时间:2016-04-12 08:59:59

标签: python python-2.7 matplotlib surface

我一直在四处寻找答案,但我似乎无法理解为什么在我的代码中我无法将投影轮廓显示在表面“背后”。

from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import numpy as np

fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.array([[200,800,1500,2000,3000],[200,700,1500,2000,3000],[200,800,1500,2000,3000],[200,800,1500,2000,3000]])
Y = np.array([[50,50,50,50,50],[350,350,350,350,350],[500,500,500,500,500],[1000,1000,1000,1000,1000]])
Z = np.array([[0,0,33,64,71],[44,62,69,74,76],[59,67,72,75,77],[63,68,73,76,77]])

ax.plot_surface(X, Y, Z, rstride=1, cstride=1, alpha=0.5)
cset = ax.contourf(X, Y, Z, zdir='z', offset=0, cmap=cm.coolwarm)
cset = ax.contourf(X, Y, Z, zdir='x', offset=200, cmap=cm.coolwarm)
cset = ax.contourf(X, Y, Z, zdir='y', offset=1000, cmap=cm.coolwarm)

ax.set_xlabel('X')
ax.set_xlim(200, 3000)
ax.set_ylabel('Y')
ax.set_ylim(0, 1000)
ax.set_zlabel('Z')
ax.set_zlim(0, 100)

plt.show()

我一直使用此页面中的填充轮廓图作为模板:http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#scatter-plots

目前我能得到的最好的方法是改变轮廓的alpha值。我也尝试在轮廓之后绘制表面,但这并没有改变任何东西。

欢迎任何建议!

1 个答案:

答案 0 :(得分:3)

您遇到的问题是matplotlib中众所周知的bug / missing feature。引用a co-lead developer of matplotlib

  

据我所知,所有的3D绘图都是一种黑客攻击。

问题可归结为一个接一个地绘制连续的曲面块,使得每个曲面完全位于其他任何一个之后,或者完全位于其前面。这意味着任何两个物体只能从某个角度正确绘制,并且不能保证所有物体都能以合理的感兴趣角度以正确的顺序绘制。

有人会认为为各种对象设置zorder属性可能会影响结果,但是this is not the case,因为

  

将绘图拆分为“上方”和“下方”是以某种神秘的方式确定的

in other words

  

Axes3D忽略zorder并按照它认为的顺序绘制艺术家。

这表现在各种各样的3d图中,例如plotting text with surfacesplotting complicated surfaces,甚至plotting 3d bar plots时(尽管可以预期更容易确定内部的绘图顺序)一个函数调用)。

对于使用单个命令绘制的曲面(即包含单个Poly3DCollection的曲面),您可以使用set_zsort()方法为matplotlib提供关于首选绘图顺序的非常粗略的提示。除此之外,您唯一的选择是移动您的表面和视角(如果可能的话),使问题不可见,或者至少不完全明显。 @tcaswell提出的另一个选择是to use mayavi而不是mplot3d(但我自己从未这样做过)。