2011-03-11 69 views
3

我想在3D空間中做這樣的事情:http://matplotlib.sourceforge.net/_images/86cbd17f31.png。基本上我想突出表面圖的一部分。有什麼建議麼?如何註釋/突出顯示MatPlotLib中的3D圖

+0

看到我更新的答案。我以前的回答是離開的。我可以推薦你在標題中將「註釋」改爲「突出顯示」嗎? – Paul 2011-03-12 03:32:08

+0

我根據你的評論更新了答案。這有點哈克。我無法找到保存補丁的zorder或設置plot_surface的zorder的好方法。 'plot_surface'似乎弄亂了事物的zorder,我不知道如何覆蓋它。我必須通過在一個背板上繪製一個不可見的等高線圖來解決這個問題。 – Paul 2011-03-13 18:52:31

+0

@保羅這是完美的,謝謝! – ofosho 2011-03-13 19:31:50

回答

6

EDIT3(它取代了非常錯誤引導前面的答案)

再次更新。請參閱評論

如果向下鑽取到由圖產生的多邊形集合,您可以修改曲面圖的面部顏色。它做了一些神奇的陰影,並根據zorder對顏色列表重新排序,所以我很難找出如何將指定的陰影保留在未加亮區域,但仍然能夠對感興趣區域進行索引。這是一種可行的方法。我希望你想要陰影面,而不是某種3D半透明列。這也可以完成,但我認爲很難說出什麼是突出顯示的,並且定義zorder會非常棘手。

enter image description here

enter image description here

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() 
+0

我不認爲這是OP想要的。我認爲他們想在3D中創建一個突出顯示的區域 - 基本上是一個三維的直線多邊形,alpha <1。我還沒有想出一個直接的方法來做到這一點。 – JoshAdel 2011-03-11 18:52:32

+0

是的,我以前的回答完全是錯誤的答案!我讀了「註釋」,認爲它可能只意味着一件事。 – Paul 2011-03-12 03:31:02

+0

看起來更合理。我想象的是一個由3d表面等分的矩形框(3D),但這看起來是一個很好的解決方案。 – JoshAdel 2011-03-12 03:55:58