2017-11-22 46 views
1

matplotlib 처리 및 선택을 사용하여 드래그 가능한 라인 클래스를 만들려고합니다. 목표는 그래프에 다른 임계 값과 간격을 설정하는 것입니다. 여기 코드는 다음과 같습니다드래그 가능한 라인은 Matplotlib에서 서로 선택합니다.

import matplotlib.pyplot as plt 
import matplotlib.lines as lines 
import numpy as np 

class draggable_lines: 

    def __init__(self, ax, kind, XorY): 

     self.ax = ax 
     self.c = ax.get_figure().canvas 
     self.o = kind 
     self.XorY = XorY 

     if kind == "h": 
      x = [-1, 1] 
      y = [XorY, XorY] 

     elif kind == "v": 
      x = [XorY, XorY] 
      y = [-1, 1] 

     else: 
      print("choose h or v line") 

     self.line = lines.Line2D(x, y, picker=5) 
     self.ax.add_line(self.line) 
     self.c.draw() 
     sid = self.c.mpl_connect('pick_event', self.clickonline) 

    # pick line when I select it 
    def clickonline(self, event): 

     self.active_line = event.artist 
     print("line selected ", event.artist) 
     self.follower = self.c.mpl_connect("motion_notify_event", self.followmouse) 
     self.releaser = self.c.mpl_connect("button_press_event", self.releaseonclick) 

    # The selected line must follow the mouse 
    def followmouse(self, event): 

     if self.o == "h": 
      self.line.set_ydata([event.ydata, event.ydata]) 
     else: 
      self.line.set_xdata([event.xdata, event.xdata]) 

     self.c.draw() 

    # release line on click 
    def releaseonclick(self, event): 

     if self.o == "h": 
      self.XorY = self.line.get_ydata()[0] 
     else: 
      self.XorY = self.line.get_xdata()[0] 

     print (self.XorY) 

     self.c.mpl_disconnect(self.releaser) 
     self.c.mpl_disconnect(self.follower) 


plt.ion() 
fig = plt.figure() 
ax = fig.add_subplot(111) 
Vline = draggable_lines(ax, "h", 0.5) 
Tline = draggable_lines(ax, "v", 0.5) 
Tline2 = draggable_lines(ax, "v", 0.1) 

동작은 I (나는 줄을 놓으면 그것은 또한 선택을 통지하는 경우에도) 단 1 회선을 사용하는 경우 예상되는 것입니다.

한 줄 이상을 사용할 때 동시에 모두 선택합니다!

나는 이벤트 관리자 기능을 오해하고 있다고 생각하지만 다른 객체를 잘 이해할 수 없다 (나는 print("line selected ", event.artist)에서 볼 수 있듯이) 자신과 다른 객체를 선택해야만한다!

답변

0

다른 질문을 할 수도 있습니다. matplotlib은 어떤 라인을 클릭하면 드래그 할 것인지 어떻게 알 수 있습니까? 답변 : 3 개의 콜백 (각 줄마다 하나씩)이 모두 실행되기 때문에 그렇지 않습니다. 다른 주에

if event.artist == self.line: 
    # register other callbacks 

(:

라인을 클릭하면 솔루션을 먼저 확인에 따라서입니다 실제로 'pick_event' 콜백 내에서 이동하는 라인입니다 당신은 너무 자주 canvas.draw()를 호출하지 혜택을 누릴 것입니다, 대신 canvas.draw_idle())

import matplotlib.pyplot as plt 
import matplotlib.lines as lines 

class draggable_lines: 
    def __init__(self, ax, kind, XorY): 
     self.ax = ax 
     self.c = ax.get_figure().canvas 
     self.o = kind 
     self.XorY = XorY 

     if kind == "h": 
      x = [-1, 1] 
      y = [XorY, XorY] 

     elif kind == "v": 
      x = [XorY, XorY] 
      y = [-1, 1] 
     self.line = lines.Line2D(x, y, picker=5) 
     self.ax.add_line(self.line) 
     self.c.draw_idle() 
     self.sid = self.c.mpl_connect('pick_event', self.clickonline) 

    def clickonline(self, event): 
     if event.artist == self.line: 
      print("line selected ", event.artist) 
      self.follower = self.c.mpl_connect("motion_notify_event", self.followmouse) 
      self.releaser = self.c.mpl_connect("button_press_event", self.releaseonclick) 

    def followmouse(self, event): 
     if self.o == "h": 
      self.line.set_ydata([event.ydata, event.ydata]) 
     else: 
      self.line.set_xdata([event.xdata, event.xdata]) 
     self.c.draw_idle() 

    def releaseonclick(self, event): 
     if self.o == "h": 
      self.XorY = self.line.get_ydata()[0] 
     else: 
      self.XorY = self.line.get_xdata()[0] 

     print (self.XorY) 

     self.c.mpl_disconnect(self.releaser) 
     self.c.mpl_disconnect(self.follower) 

fig = plt.figure() 
ax = fig.add_subplot(111) 
Vline = draggable_lines(ax, "h", 0.5) 
Tline = draggable_lines(ax, "v", 0.5) 
Tline2 = draggable_lines(ax, "v", 0.1) 
plt.show()