如何在MatPlotLib中注释/高亮3D图形

3 投票
1 回答
2772 浏览
提问于 2025-04-16 13:31

我想在三维空间里做类似这个的效果:http://matplotlib.sourceforge.net/_images/86cbd17f31.png。简单来说,我想在一个表面图上突出显示一部分。有什么建议吗?

1 个回答

8

编辑3(这替代了之前一个非常错误的回答)

再次更新。请查看评论

如果你想修改表面图的面颜色,可以深入到绘图生成的多边形集合中去。这个过程会进行一些神奇的阴影处理,并根据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()

撰写回答