2011-03-11 4 views
3

3D 공간에서 http://matplotlib.sourceforge.net/_images/86cbd17f31.png과 같이하고 싶습니다. 기본적으로 나는 표면 플롯의 일부를 강조하고 싶다. 어떤 제안?MatPlotLib에서 주석을 달거나 강조 표시하는 방법

+0

enter image description here

내 업데이트 된 대답을 참조하십시오. 나의 이전 대답은 벗어났다. 제목에 '주석 달기'를 '강조 표시'로 변경하는 것이 좋습니다. – Paul

+0

귀하의 의견을 바탕으로 답변을 업데이트했습니다. 조금 해키 야. 나는 패치의 zorder를 보존하거나 plot_surface의 zorder를 설정하는 좋은 방법을 찾지 못했습니다. 'plot_surface'는 일의 zorder를 엉망으로 만드는 것처럼 보입니다. 나는 그것을 무시하는 법을 모르겠습니다. 하나의 후면 판에 보이지 않는 등고선 플롯을 플로팅하여이 문제를 해결해야했습니다. – Paul

+0

@Paul 완벽 해. 고마워! – ofosho

답변

6

EDIT3 다시 업데이트

(이것은 아주 잘못 인도 이전의 대답을 대체합니다). 의견보기

플롯에서 생성 된 다각형 컬렉션으로 드릴 다운하면 표면 플롯의면 색상을 수정할 수 있습니다. 일부 마술 음영을하고 zorder에 따라 색상 목록을 다시 주문하므로 강조 표시되지 않은 영역에 할당 된 음영을 유지하는 방법을 알아내는 데 어려움이 있지만 관심 영역의 색인을 생성 할 수 있습니다. 다음은 작동하는 방법입니다. 음영 처리 된 얼굴을 원했고 3D 반투명 열이 아닌 것을 원하셨습니까? 이것은 또한 수행 될 수 있지만, 나는 무엇이 강조되어 있고 zorder를 정의하는 것이 매우 까다로운지를 말하는 것은 매우 어려울 것이라고 생각한다. 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 인 3D의 직선형 폴리곤입니다. 아직이 작업을 수행하는 간단한 방법을 찾지 못했습니다. – JoshAdel

+0

예, 이전의 대답은 완전히 잘못된 대답이었습니다! 나는 "주석 (annotation)"을 읽었고 단지 하나의 것을 의미 할 수 있다고 생각했다. – Paul

+0

는 더 합리적인 것처럼 보입니다. 3D 표면에 의해 2 등분 된 직사각형 박스 (3D)를 상상하고 있었지만 이것은 좋은 해결책처럼 보입니다. – JoshAdel

관련 문제