【问题标题】:How to annotate/highlight a 3d plot in MatPlotLib如何在 MatPlotLib 中注释/突出显示 3d 图
【发布时间】:2011-03-11 17:31:52
【问题描述】:

我想做这样的事情:http://matplotlib.sourceforge.net/_images/86cbd17f31.png 在 3d 空间中。基本上我想突出显示曲面图的一部分。有什么建议吗?

【问题讨论】:

  • 查看我的更新答案。我之前的回答很离谱。我可以建议您将标题中的“注释”更改为“突出显示”吗?
  • 我根据您的评论更新了答案。这有点骇人听闻。我找不到保存补丁 zorder 或设置 plot_surface 的 zorder 的好方法。 plot_surface 似乎弄乱了事物的顺序,我不知道如何覆盖它。我不得不通过在一个背板上绘制一个不可见的等高线图来解决这个问题。
  • @Paul 太好了,谢谢!

标签: python matplotlib


【解决方案1】:

edit3(这取代了一个非常错误的先前答案)

再次更新。见评论

如果您深入到由绘图生成的多边形集合,您可以修改表面绘图的面颜色。它做了一些神奇的着色并根据 zorder 重新排序颜色列表,所以我在弄清楚如何将分配的阴影保持在未突出显示的区域中但仍然能够索引感兴趣的区域时遇到了一些麻烦。这是一种有效的方法。我希望你想要阴影面,而不是某种 3D 半透明列。也可以这样做,但我认为很难分辨出突出显示的内容,并且定义 zorder 也非常棘手。

import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import mpl_toolkits.mplot3d.art3d as art3d
from matplotlib.patches import Rectangle, PathPatch

fig = plt.figure()
ax = fig.gca(projection='3d')
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)

xlo = X.min()
xhi = X.max()
ylo = Y.min()
yhi = Y.max()
zlo = -2
zhi = 2

surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, linewidth=1, zorder=100)
cset = ax.contour(X, Y, Z, zdir='z', offset=zlo, alpha=0.0)

def highlight((xmin, xmax),(ymin, ymax)):
    # draw highlight on xz plane
    p1 = Rectangle((ymin,zlo),(ymax-ymin),(zhi-zlo), color='y', alpha=0.5, zorder=0)
    ax.add_patch(p1)
    art3d.pathpatch_2d_to_3d(p1, z=xlo, zdir='x')

    # draw highlight on yz plane
    p2 = Rectangle((xmin,zlo),(xmax-xmin),(zhi-zlo), color='y', alpha=0.5, zorder=0)
    ax.add_patch(p2)
    art3d.pathpatch_2d_to_3d(p2, z=yhi, zdir='y')

    # define a region to highlight
    highlight = (X>xmin)&(X<xmax)&(Y>ymin)&(Y<ymax)
    coll = ax.collections[0]
    # get the original color shading (if you want to keep that effect)
    colors = coll._facecolors_original
    #colors = coll.get_facecolors()
    # they are stored as a list for some reason so get the flat indicies
    for idx in np.where(highlight[:-1,:-1].flat)[0]:
        # and modifly one-by-one
        color = colors[idx][:]
        colors[idx][0] = color[2]  # swap red with blue
        colors[idx][3] = color[0]
        colors[idx][4] = .2  #change alpha
    # re-set the face colors
    coll.set_facecolors(colors)

highlight((-3,0),(-3,1))

ax.set_xlim3d(xlo, xhi)
ax.set_ylim3d(ylo, yhi)
ax.set_zlim3d(zlo, zhi)

plt.show()

【讨论】:

  • 我认为这不是 OP 想要的。我认为他们想在 3D 中创建一个突出显示的区域——基本上是一个 3D 中的直线多边形,alpha
  • 是的,我之前的答案完全是错误的答案!我读了“注释”,并认为它可能只意味着一件事。
  • 看起来更合理。我在想象一个被 3d 表面一分为二的矩形框(3d),但这看起来是一个很好的解决方案。
  • 我看到我的问题措辞不佳,但我实际上只是想突出显示 在表面图之后 的网格部分。但是,此解决方案更加优雅,感谢您的发布!为了将来参考,我仍然很好奇我的意图是否可行?
猜你喜欢
  • 1970-01-01
  • 2012-05-09
  • 2020-07-31
  • 1970-01-01
  • 2020-06-23
  • 2012-05-15
  • 2019-12-25
  • 2022-12-10
  • 2013-03-02
相关资源
最近更新 更多