2011-01-10 10 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(...)を呼び出す必要があり、b)は、手動で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

絶対に、ありがとう!私はそれをそこに残すべきではなかった。また、私はおそらくこれを更新する必要があります...軸ではなく特定のアーティストを渡す方が合理的でしょう。 –

関連する問題