2012-05-27 4 views
0

에 클릭 된 라인 검출 내 시작 코드wxPython에의하기 matplotlib - 3D 라인 플롯

이 코드는 막대 그래프를 생성로 this example code을 사용하고 있습니다. 사용자가 막대 그래프의 실제 막대를 클릭하면 이벤트가 트리거되고 개별 막대의 경계 상자 좌표가 표시됩니다. 이것은 on_pick 함수에서 발생합니다.

막대 그래프 대신 코드를 수정했습니다. Axes3D line plot입니다. 이 XYZ 좌표계에 여러 개의 선이 그려져 있습니다. 필요한 것은 클릭 한 줄을 인식하는 것입니다. 막대 그래프와 마찬가지로 경계 상자가 3D 플롯에서 작동하지 않는 것으로 보입니다.

나는 pick_event 문서를 조사했지만 해결 방법을 찾지 못했습니다. 클릭 한 위치의 x, y 좌표를 간단히 감지 할 수 있지만 어떤 각도에서도 플롯을 회전 할 수 있기 때문에 어떤 선이 실제로 클릭되었는지 감지하는 것이 매우 어려워 보입니다. 특히 시점에 따라 겹칠 수 있기 때문에 특히 그렇습니다.

시간과 도움에 감사드립니다.

답변

2

클릭 한 곡선 만 알면 그리 어렵지 않습니다. line_picker()를 만들어 마우스 위치가 커브에 충분히 근접한 지 여부를 확인해야합니다.

line_picker() 점과 선분 사이의 거리를 계산해야하는데, 약간 어렵습니다. 곡선의 선형 보간법을 사용하여이 문제를 해결합니다.

여기 코드는 2000 포인트로 곡선을 보간하고, 곡선의 마우스 위치가 5 픽셀보다 작 으면 곡선이 선택됩니다.

import matplotlib as mpl 
from mpl_toolkits.mplot3d import Axes3D 
import numpy as np 
import matplotlib.pyplot as plt 

def line_picker(line, me): 
    if me.xdata is None: return False, dict()  
    x, y = me.x, me.y 
    xdata, ydata = line.axes.transData.transform(np.array(line.get_data()).T).T 
    index = np.arange(len(xdata)) 
    index2 = np.linspace(0, index[-1], 2000) 
    xdata2 = np.interp(index2, index, xdata) 
    ydata2 = np.interp(index2, index, ydata) 
    d = np.sqrt((xdata2-x)**2. + (ydata2-y)**2.) 
    if np.min(d) < 5: 
     return True, {} 
    else: 
     return False, {} 

mpl.rcParams['legend.fontsize'] = 10 

fig = plt.figure() 
ax = fig.gca(projection='3d') 
theta = np.linspace(-4 * np.pi, 4 * np.pi, 100) 
z = np.linspace(-2, 2, 100) 
r = z**2 + 1 
x = r * np.sin(theta) 
y = r * np.cos(theta) 
line1 = ax.plot(x, y, z, label='parametric curve', picker=line_picker)[0] 

t = np.linspace(-1, 1, 100) 
x = 4*np.sin(10*t) 
y = 4*np.cos(10*t) 
z = t**2*5-3 

line2 = ax.plot(x, y, z, label="second", picker=line_picker)[0] 

ax.legend() 

def onpick(event): 
    print [line1, line2].index(event.artist) 

fig.canvas.mpl_connect('pick_event', onpick) 

plt.show() 
+0

대단히 고맙습니다. 이것이 내가 필요한 것입니다. 각 플롯 명령 다음에 [0]이 무엇인지 설명해 주실 수 있습니까? 나는 파이썬에 익숙하지 않으므로 그것이 분명하다면 나를 용서해주십시오. 감사! –

+0

plot() Line2D 객체의 목록을 반환하여 Line2D 객체를 직접 가져옵니다. [0]을 사용합니다. – HYRY