2017-11-22 7 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) 

挙動は(私はラインを解放するとき、それはまた、選択を通知した場合でも)のみ1行を使用しているとき、私が期待したものです。

複数の行を使用している場合、同時にすべての行が選択されます。

私はイベントマネージャーの機能を誤解していると思いますが、別のオブジェクトがよく分かります(私がprint("line selected ", event.artist)で見ることができるように)自分自身と別のものを選択しなければならない理由を理解できません!

答えて

0

お互いに尋ねることができます:どのラインをクリックすればどのラインをドラッグするのかmatplotlibはどのようにしたらよいでしょうか?答え:それは3つのコールバックを持っているので、1行に1つのコールバックがあり、すべてを実行します。

ラインがクリックされた場合の解決策は、最初のチェックにしたがってでは、実際に'pick_event'コールバックの内側に移動するラインである:

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

(別のノートで:あなたはそれほど頻繁に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() 
関連する問題