2011-01-10 2 views

답변

54

늦은 편집/부끄러워 플러그 : 이제 더 많은 기능을 추가하여 mpldatacursor으로 사용할 수 있습니다. mpldatacursor.datacursor()을 호출하면 모든 matplotlib 아티스트 (이미지의 z 값에 대한 기본 지원 포함)에서 사용할 수 있습니다.


는 지금까지 내가 아는 한, 이미 구현 한이 아니지만, 비슷한 쓰기 너무 어렵지 않다 : 그것은 적어도처럼 보인다으로

import matplotlib.pyplot as plt 

class DataCursor(object): 
    text_template = 'x: %0.2f\ny: %0.2f' 
    x, y = 0.0, 0.0 
    xoffset, yoffset = -20, 20 
    text_template = 'x: %0.2f\ny: %0.2f' 

    def __init__(self, ax): 
     self.ax = ax 
     self.annotation = ax.annotate(self.text_template, 
       xy=(self.x, self.y), xytext=(self.xoffset, self.yoffset), 
       textcoords='offset points', ha='right', va='bottom', 
       bbox=dict(boxstyle='round,pad=0.5', fc='yellow', alpha=0.5), 
       arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0') 
       ) 
     self.annotation.set_visible(False) 

    def __call__(self, event): 
     self.event = event 
     # xdata, ydata = event.artist.get_data() 
     # self.x, self.y = xdata[event.ind], ydata[event.ind] 
     self.x, self.y = event.mouseevent.xdata, event.mouseevent.ydata 
     if self.x is not None: 
      self.annotation.xy = self.x, self.y 
      self.annotation.set_text(self.text_template % (self.x, self.y)) 
      self.annotation.set_visible(True) 
      event.canvas.draw() 

fig = plt.figure() 
line, = plt.plot(range(10), 'ro-') 
fig.canvas.mpl_connect('pick_event', DataCursor(plt.gca())) 
line.set_picker(5) # Tolerance in points 

Datacursor-ish thing in matplotlib

을 소수의 사람들이 이것을 사용하고 있으며 아래에 업데이트 된 버전을 추가했습니다.

새 버전은 더 간단한 사용법과 더 많은 문서 (최소한 아주 작은 비트)를 가지고 있습니다.

기본적으로 당신은 유사한이로 사용하십시오 :

plt.figure() 
plt.subplot(2,1,1) 
line1, = plt.plot(range(10), 'ro-') 
plt.subplot(2,1,2) 
line2, = plt.plot(range(10), 'bo-') 

DataCursor([line1, line2]) 

plt.show() 

의 주요 차이점 A) 수동 line.set_picker(...)를 호출 할 필요가, 나), 수동 fig.canvas.mpl_connect를 호출 할 필요가 없다 없다는 것을하고 C)이 버전은 여러 축과 여러 개의 숫자를 처리합니다.

from matplotlib import cbook 

class DataCursor(object): 
    """A simple data cursor widget that displays the x,y location of a 
    matplotlib artist when it is selected.""" 
    def __init__(self, artists, tolerance=5, offsets=(-20, 20), 
       template='x: %0.2f\ny: %0.2f', display_all=False): 
     """Create the data cursor and connect it to the relevant figure. 
     "artists" is the matplotlib artist or sequence of artists that will be 
      selected. 
     "tolerance" is the radius (in points) that the mouse click must be 
      within to select the artist. 
     "offsets" is a tuple of (x,y) offsets in points from the selected 
      point to the displayed annotation box 
     "template" is the format string to be used. Note: For compatibility 
      with older versions of python, this uses the old-style (%) 
      formatting specification. 
     "display_all" controls whether more than one annotation box will 
      be shown if there are multiple axes. Only one will be shown 
      per-axis, regardless. 
     """ 
     self.template = template 
     self.offsets = offsets 
     self.display_all = display_all 
     if not cbook.iterable(artists): 
      artists = [artists] 
     self.artists = artists 
     self.axes = tuple(set(art.axes for art in self.artists)) 
     self.figures = tuple(set(ax.figure for ax in self.axes)) 

     self.annotations = {} 
     for ax in self.axes: 
      self.annotations[ax] = self.annotate(ax) 

     for artist in self.artists: 
      artist.set_picker(tolerance) 
     for fig in self.figures: 
      fig.canvas.mpl_connect('pick_event', self) 

    def annotate(self, ax): 
     """Draws and hides the annotation box for the given axis "ax".""" 
     annotation = ax.annotate(self.template, xy=(0, 0), ha='right', 
       xytext=self.offsets, textcoords='offset points', va='bottom', 
       bbox=dict(boxstyle='round,pad=0.5', fc='yellow', alpha=0.5), 
       arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0') 
       ) 
     annotation.set_visible(False) 
     return annotation 

    def __call__(self, event): 
     """Intended to be called through "mpl_connect".""" 
     # Rather than trying to interpolate, just display the clicked coords 
     # This will only be called if it's within "tolerance", anyway. 
     x, y = event.mouseevent.xdata, event.mouseevent.ydata 
     annotation = self.annotations[event.artist.axes] 
     if x is not None: 
      if not self.display_all: 
       # Hide any other annotation boxes... 
       for ann in self.annotations.values(): 
        ann.set_visible(False) 
      # Update the annotation in the current axis.. 
      annotation.xy = x, y 
      annotation.set_text(self.template % (x, y)) 
      annotation.set_visible(True) 
      event.canvas.draw() 

if __name__ == '__main__': 
    import matplotlib.pyplot as plt 
    plt.figure() 
    plt.subplot(2,1,1) 
    line1, = plt.plot(range(10), 'ro-') 
    plt.subplot(2,1,2) 
    line2, = plt.plot(range(10), 'bo-') 

    DataCursor([line1, line2]) 

    plt.show() 
+0

너무 멋지다. 고맙습니다! – unutbu

+0

Joe, 나는 사용되지 않는 것으로 보였기 때문에'xdata, ydata = event.artist.get_data()'를 주석 처리하고 [question]을 제기했다. (http://stackoverflow.com/q/8956794/190597) . 희망은 그것이 좋아. – unutbu

+0

물론 감사합니다! 나는 거기에두면 안된다. 또한 아마도 이것을 업데이트해야합니다 ... 축이 아닌 특정 아티스트를 전달하는 것이 더 합리적입니다. –

관련 문제