2017-05-15 3 views
0

사용자가 특정 지점의 정확한 값을 볼 수 있도록 드래그 가능 마커가 필요합니다. 표식은 플롯의 플롯 된 선 위로 만 이동해야합니다. pyplot에서 요소를 드래그하는 방법을 찾았지만 플롯 된 날짜에만이 마커를 이동하는 방법을 찾지 못했습니다.matplotlib의 드래그 가능한 마커

답변

0

다음은 드래그 가능한 마커의 예입니다.이 마커는 항상 줄에 가장 가까운 지점을 표시합니다.

import numpy as np 
import matplotlib.pyplot as plt 

x = np.arange(60) 
y = np.sin(x)*np.log(x+1) 

fig, ax = plt.subplots() 
ax.plot(x,y, marker="o", ms=4) 

class DraggableMarker(): 
    def __init__(self,ax=None, lines=None): 
     if ax == None: 
      self.ax = plt.gca() 
     else: 
      self.ax=ax 
     if lines==None: 
      self.lines=self.ax.lines 
     else: 
      self.lines=lines 
     self.lines = self.lines[:] 
     self.tx = [self.ax.text(0,0,"") for l in self.lines] 
     self.marker = [self.ax.plot([0],[0], marker="o", color="red")[0] for l in self.lines] 

     self.draggable=False 

     self.c1 = self.ax.figure.canvas.mpl_connect("button_press_event", self.click) 
     self.c2 = self.ax.figure.canvas.mpl_connect("button_release_event", self.release) 
     self.c3 = self.ax.figure.canvas.mpl_connect("motion_notify_event", self.drag) 

    def click(self,event): 
     if event.button==1: 
      #leftclick 
      self.draggable=True 
      self.update(event) 
     elif event.button==3: 
      self.draggable=False 
     [tx.set_visible(self.draggable) for tx in self.tx] 
     [m.set_visible(self.draggable) for m in self.marker] 
     ax.figure.canvas.draw_idle()   

    def drag(self, event): 
     if self.draggable: 
      self.update(event) 
      ax.figure.canvas.draw_idle() 

    def release(self,event): 
     self.draggable=False 

    def update(self, event): 
     for i, line in enumerate(self.lines): 
      x,y = self.get_closest(line, event.xdata) 
      self.tx[i].set_position((x,y)) 
      self.tx[i].set_text("x:{}\ny:{}".format(x,y)) 
      self.marker[i].set_data([x],[y]) 

    def get_closest(self,line, mx): 
     x,y = line.get_data() 
     mini = np.argmin(np.abs(x-mx)) 
     return x[mini], y[mini] 

dm = DraggableMarker() 

plt.show() 
관련 문제