나는 플롯 된 데이터를 시각적으로 윈도우에 표시 할 수 있도록 드래그 가능한 라인이있는 간단한 GUI로 작업하고 있습니다. 때,matplotlib contains를 하나의 객체로 제한하려면 어떻게합니까?
fig = plt.figure()
ax = fig.add_subplot(111)
vl1 = DraggableLine('vertical', ax, 3)
vl2 = DraggableLine('vertical', ax, 6)
ax.set_xlim([0, 10])
plt.show()
을하지만 :
import numpy as np
import matplotlib.pyplot as plt
class DraggableLine:
def __init__(self, orientation, ax, position):
if orientation.lower() == 'horizontal':
self.myline, = ax.plot(ax.get_xlim(), np.array([1, 1])*position)
self.orientation = orientation.lower()
elif orientation.lower() == 'vertical':
self.myline, = ax.plot(np.array([1, 1])*position, ax.get_ylim())
self.orientation = orientation.lower()
else:
# throw an error
pass
self.parentfig = self.myline.figure.canvas
self.parentax = ax
self.clickpress = self.parentfig.mpl_connect('button_press_event', self.on_click) # Execute on mouse click
self.clicked = False
def on_click(self, event):
# Executed on mouse click
if event.inaxes != self.parentax: return # See if the mouse is over the parent axes object
# See if the click is on top of this line object
contains, attrs = self.myline.contains(event)
if not contains: return
self.mousemotion = self.parentfig.mpl_connect('motion_notify_event', self.on_motion)
self.clickrelease = self.parentfig.mpl_connect('button_release_event', self.on_release)
self.clicked = True
def on_motion(self, event):
# Executed on mouse motion
if not self.clicked: return # See if we've clicked yet
if event.inaxes != self.parentax: return # See if we're moving over the parent axes object
if self.orientation == 'vertical':
self.myline.set_xdata(np.array([1, 1])*event.xdata)
self.myline.set_ydata(self.parentax.get_ylim())
elif self.orientation == 'horizontal':
self.myline.set_xdata(self.parentax.get_xlim())
self.myline.set_ydata(np.array([1, 1])*event.ydata)
self.parentfig.draw()
def on_release(self, event):
self.clicked = False
self.parentfig.mpl_disconnect(self.mousemotion)
self.parentfig.mpl_disconnect(self.clickrelease)
self.parentfig.draw()
예상대로 작동 라인을 생성 matplotlib's event handling documentation 작업
나는 드래그 윈도우 라인의 초기 버전을 구현 할 수있었습니다 라인이 쌓이면 matplotlib.lines.Line2D.contains()
은 하나의 오브젝트가 다른 오브젝트에 의해 가려져 있다는 것을 모르기 때문에 단일 라인을 이동하는 기능이 손실됩니다. 그래서 우리는 플롯이 닫힐 때까지 물체의 덩어리를 끌고 떠납니다.
이 문제를 완화하기 위해 이미 구현 된 방법이 있습니까? 그렇지 않다면 마우스를 놓을 때 DraggableLine
클래스의 인스턴스에 대해 부모 축의 자식을 쿼리하고 위치를 확인한 다음 필요한 경우 'button_press_event'
을 연결/연결 해제하는 방법을 생각해 볼 수 있습니다. 그게 가장 합리적인 계산 시간을 현명하게하는지 모르겠습니다.
그것은 생각할 수 없다 줄 사이에 어떤 종류의 계층 구조를 만들지 만 둘 다 클릭하면 단 하나만 움직이십시오. 나는 그것을 위해 전역이 필요하거나 두 번째 생성자에 첫 번째 줄을 전달해야한다고 생각한다. –
@AndrasDeak 그건 내가 마지막 단락에서 얻은 것입니다. "글로벌"은 부모 축의 자식이 될 것이고이 클래스의 인스턴스를 필터링 할 수 있습니다. – excaza