Matplotlib - 在同一轴上绘制两个3D曲面时错误重叠

And*_*cer 17 python matplotlib

我试图用plot_surface命令在matplotlib中的相同轴上绘制两个3D表面.

fig = plt.figure()
fig.figsize = fig_size
ax = fig.gca(projection='3d')

surf = ax.plot_surface(X, Y, Exp_Fric_map, alpha = 1, rstride=1, cstride=1, cmap=cm.winter, linewidth=0.5, antialiased=True)
surf = ax.plot_surface(X, Y, Fric_map, alpha = 1, rstride=1, cstride=1, cmap=cm.autumn,linewidth=0.5, antialiased=True)
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,在查看绘图时,并不总是正确的表面是"在顶部",例如在图中:

示例图

在后角(200N,轴上为2.5Hz),当实际上黄色 - 红色更靠近观察者时,蓝绿色表面位于"顶部".如果我旋转图:

第二个例子

那么事情看起来还不错,蓝绿色表面位于200N和2.5Hz(现在在左侧)的黄红色表面下方.我尝试过搜索stackoverflow和Google,但找不到解决方案的任何类似问题.

我在Linux上使用Python 2.7.3,Numpy 1.6.1和Matplotlib 1.1.1rc.

Sky*_*ler 11

这就像绘画一样.哪一个'在顶部'取决于你最后绘制的那个.

您可能希望使用zorder属性来告诉matplotlib表面的绘制顺序.

例如:

ax.plot_surface(X, Y, Exp_Fric_map, alpha = 1, rstride=1, cstride=1, cmap=cm.winter, linewidth=0.5, antialiased=True, zorder = 0.5)
ax.plot_surface(X, Y, Fric_map, alpha = 1, rstride=1, cstride=1, cmap=cm.autumn,linewidth=0.5, antialiased=True, zorder = 0.3)
Run Code Online (Sandbox Code Playgroud)

更新:

我已经运行了几个测试,我相信这是一个matplotlib 的错误,同时在一个图中绘制多个表面.例如,它使我们的3D世界中不应存在的一些表面如:

在此输入图像描述

,尝试后我看不到有效的解决方案.正如我所说,因果关系是绘画的顺序:matplotlib总是一个一个地绘画.如果表面的一部分应位于顶部,而另一部分应位于底部,则matplotlib将出错.

因此我的建议是停止解决这个问题,除非你想为matplotlib做贡献,否则浪费时间.如果你有必要解决这个问题,我建议你去找另一个绘图工具来完成你的工作.

  • 截至2016年8月,此问题仍然存在. (2认同)
  • 这非常令人沮丧. (2认同)

Igo*_*gor 10

matplotlib常见问题解答此处记录了此行为。同一页面上建议安装可以在3D绘图中正常使用的Mayavi

  • 它的界面与matplotlib非常相似。
  • 它的主要问题是在python 3上安装它仍然很棘手。(现在变得容易得多)

这是演示“ matplotlib vs mayavi”的比较:

# generate data
import numpy as np

x = np.arange(-2, 2, 0.1)
y = np.arange(-2, 2, 0.1)
mx, my = np.meshgrid(x, y, indexing='ij')
mz1 = np.abs(mx) + np.abs(my)
mz2 = mx ** 2 + my ** 2

# A fix for "API 'QString' has already been set to version 1"
# see https://github.com/enthought/pyface/issues/286#issuecomment-335436808
from sys import version_info
if version_info[0] < 3:
    import pyface.qt


def v1_matplotlib():
    from matplotlib import pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D

    fig = plt.figure()
    ax = fig.gca(projection='3d')
    surf1 = ax.plot_surface(mx, my, mz1, cmap='winter')
    surf2 = ax.plot_surface(mx, my, mz2, cmap='autumn')
    ax.view_init(azim=60, elev=16)
    fig.show()


def v2_mayavi(transparency):
    from mayavi import mlab
    fig = mlab.figure()

    ax_ranges = [-2, 2, -2, 2, 0, 8]
    ax_scale = [1.0, 1.0, 0.4]
    ax_extent = ax_ranges * np.repeat(ax_scale, 2)

    surf3 = mlab.surf(mx, my, mz1, colormap='Blues')
    surf4 = mlab.surf(mx, my, mz2, colormap='Oranges')

    surf3.actor.actor.scale = ax_scale
    surf4.actor.actor.scale = ax_scale
    mlab.view(60, 74, 17, [-2.5, -4.6, -0.3])
    mlab.outline(surf3, color=(.7, .7, .7), extent=ax_extent)
    mlab.axes(surf3, color=(.7, .7, .7), extent=ax_extent,
              ranges=ax_ranges,
              xlabel='x', ylabel='y', zlabel='z')

    if transparency:
        surf3.actor.property.opacity = 0.5
        surf4.actor.property.opacity = 0.5
        fig.scene.renderer.use_depth_peeling = 1


v1_matplotlib()
v2_mayavi(False)
v2_mayavi(True)

# To install mayavi, the following currently works for me (Windows 10):
#
#   conda create --name mayavi_test_py2 python=2.7 matplotlib mayavi=4.4.0
#    (installs pyqt=4.10.4 mayavi=4.4.0 vtk=5.10.1)
#    * the `use_depth_peeling=1` got no effect. Transparency is not correct.
#    * requires `import pyface.qt` or similar workaround
#
# or
#
#   conda create --name mayavi_test_py3 python=3.6 matplotlib
#   conda activate mayavi_test_py3
#   pip install mayavi
Run Code Online (Sandbox Code Playgroud)

matplotlib vs mayavi_no_transparency vs mayavi_with_transparency