本文介绍了在matplotlib中在Surface前面显示轮廓的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找答案,但是我似乎看不出为什么在我的代码中我无法获得投影的轮廓来显示隐藏在表面之后".

I've been looking around for answers but I can't seem to see why in my code I can't get the projected contours to show up "behind" the 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

I have been using the one of the Filled Contour Plots from this page as template: http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#scatter-plots

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

At the moment the best I could get was to change the alpha value of the contours. I also tried plotting the surface after the contours but that didn't change anything.

欢迎任何建议!

推荐答案

您遇到的问题是一个众所周知的错误/matplotlib 中缺少特征.引用 matplotlib的联合首席开发人员:

The problem you're experiencing is a well-known bug/missing feature in matplotlib. Quoting a co-lead developer of matplotlib:

据我所知,所有的 3D 绘图都有点像黑客.

问题归结为连续的曲面块一个接一个地绘制,这样每个块要么完全落后于另一个,要么完全在其前面.这将意味着只能从特定角度正确绘制任何两个对象,并且不能保证所有对象都可以在合理的感兴趣角度以正确的顺序绘制.

The issue boils down to that contiguous blocks of surfaces are plotted one after the other, such that each is either fully behind any other, or fully in front of it. This will imply that any two objects are drawn properly only from certain angles, and there's no guarantee that all objects will be drawn with the proper order at reasonable angles of interest.

人们会认为为各种对象设置 zorder 属性可能会影响结果,但 这不是情况,因为

One would think that setting zorder properties for the various objects could affect the result, but this is not the case, since

拆分绘图是上方"和下方"以某种神秘的方式确定

换句话说

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

这体现在各种 3d 绘图中,例如当使用曲面绘制文本时绘制复杂曲面,甚至(即使可以期望在单个函数调用中确定绘制顺序更容易).

This manifests itself in all sorts of 3d plots, such as when plotting text with surfaces, plotting complicated surfaces, or even plotting 3d bar plots (even though one could expect that it's easier to determine the plotting order within a single function call).

对于使用单个命令绘制的表面(即,包含单个 Poly3DCollection 的表面),可以使用 set_zsort()方法向matplotlib提供非常粗略的提示首选的绘图顺序.除此之外,您唯一的选择是以某种方式(看不到或至少看不到整个问题)来移动曲面和视角(如果可能的话).@tcaswell 提出的另一个选择是 使用mayavi 而不是mplot3d(但我自己从未这样做).

For surfaces plotted with a single command (i.e. those that comprise a single Poly3DCollection) you can use the set_zsort() method to give a very crude hint to matplotlib regarding the preferred plotting order. Other than this, your only option is moving your surfaces and viewing angles around (if at all possible) in a way that the issue is not visible, or at least not entirely apparent. Another option proposed by @tcaswell is to use mayavi instead of mplot3d (but I've never done that myself).

这篇关于在matplotlib中在Surface前面显示轮廓的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-17 00:43