2012-09-25 61 views
6

我目前正在使用此代碼在地圖上彈出註釋,當我點擊底圖Matplotlib圖中的一個點時。Python和Matplotlib以及帶鼠標懸停的註釋

dcc = DataCursor(self.figure.gca()) 
self.figure.canvas.mpl_connect('pick_event',dcc) 
plot_handle.set_picker(5) 
self.figure.canvas.draw() 

class DataCursor(object): 

    import matplotlib.pyplot as plt 

    text_template = 'x: %0.2f\ny: %0.2f' 
    x, y = 0.0, 0.0 
    xoffset, yoffset = -20 , 20 
    text_template = 'A: %s\nB: %s\nC: %s' 


    def __init__(self, ax): 
     self.ax = ax 
     self.annotation = ax.annotate(self.text_template, 
       xy=(self.x, self.y), xytext=(0,0), 
       textcoords='axes fraction', ha='left', va='bottom', fontsize=10, 
       bbox=dict(boxstyle='round,pad=0.5', fc='yellow', alpha=1), 
       arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0') 
       ) 
     self.annotation.set_visible(False) 
     self.annotation.draggable() 


    def __call__(self, event): 

     self.event = event 
     self.x, self.y = event.mouseevent.xdata, event.mouseevent.ydata 

     if self.x is not None: 
      glim = pickle.load(open("ListA.py","rb")) 
      tlim = pickle.load(open("ListB.py","rb")) 
      vlim = pickle.load(open("ListC.py","rb")) 
      a = glim[event.ind[0]] # ['Name'][event.ind[0]] 
      b = tlim[event.ind[0]] 
      c = vlim[event.ind[0]] 
      temp_temp=self.text_template % (a, b, c) 
      if temp_temp == self.annotation.get_text() and self.annotation.get_visible(): 
       self.annotation.set_visible(False) 
       event.canvas.draw() 
       return 
      self.annotation.xy = self.x, self.y 
      self.annotation.set_text(self.text_template % (a, b, c)) 
      self.annotation.set_visible(True) 

      event.canvas.draw() 

我想知道的是,如何使用鼠標懸停而不是點擊某個點來顯示註釋?

我看到「motion_notify_event」,但它似乎代碼獲取錯誤時,我將鼠標移動到情節區域周圍。有什麼想法嗎?

回答

8

看看this questiondemo

from matplotlib.pyplot import figure, show 
import numpy as npy 
from numpy.random import rand 


if 1: # picking on a scatter plot (matplotlib.collections.RegularPolyCollection) 

    x, y, c, s = rand(4, 100) 
    def onpick3(event): 
     ind = event.ind 
     print 'onpick3 scatter:', ind, npy.take(x, ind), npy.take(y, ind) 

    fig = figure() 
    ax1 = fig.add_subplot(111) 
    col = ax1.scatter(x, y, 100*s, c, picker=True) 
    #fig.savefig('pscoll.eps') 
    fig.canvas.mpl_connect('pick_event', onpick3) 

show() 
+0

我已經看到這兩個鏈接,但我不知道如何以我目前的格式實現它們。我也不知道「pick_event」是一個不可點擊的動作? – mcfly

+6

我接受這個答案,但這不是正確的答案。然而,Root確實鏈接了另一個關聯這個[question]的問題(http://stackoverflow.com/questions/4453143/point-and-line-tooltips-in-matplotlib/4620352#4620352),它給出了懸停和顯示的正確方法註釋。注意:我仍然使用註釋來代替wx.tooltip。它工作得很好! – mcfly

0
from mpl_toolkits.basemap import Basemap 
import matplotlib.pyplot as plt 

lat = 20.5937 
lon = 78.9629 
points_with_annotation = list() 

#Event is set for any movement and annotations are set to visible when on points with anotation 
def on_move(event): 
    visibility_changed = False 
    for point, annotation in points_with_annotation: 
     should_be_visible = (point.contains(event)[0] == True) 

     if should_be_visible != annotation.get_visible(): 
      visibility_changed = True 
      annotation.set_visible(should_be_visible) 

    if visibility_changed:   
     plt.draw() 


fig = plt.figure() 
ax = plt.axes() 

m = Basemap(projection='mill', llcrnrlat=-90, llcrnrlon=-180, urcrnrlat=90, urcrnrlon=180, resolution='c') 
m.fillcontinents(color='white', lake_color='white') 
m.drawcoastlines(linewidth=0.5, color='k') 
m.drawcountries(linewidth=0.5, color='k') 
m.drawmapboundary(fill_color='white') 

xpt, ypt = m(lon,lat) 
point, = m.plot(xpt, ypt, marker='o', markersize=5, alpha=0.85, visible=True) 
annotation = ax.annotate("Lat: %s Lon: %s" % (lat,lon), 
    xy=(xpt, ypt), xycoords='data', 
    xytext=(xpt + 1, ypt), textcoords='data', 
    horizontalalignment="left", 
    arrowprops=dict(arrowstyle="simple", 
    connectionstyle="arc3,rad=-0.2"), 
    bbox=dict(boxstyle="round", facecolor="w", 
    edgecolor="0.5", alpha=0.9) 
     ) 


annotation.set_visible(False) 
points_with_annotation.append([point, annotation]) 
on_move_id = fig.canvas.mpl_connect('motion_notify_event', on_move) 
plt.show() 

下面就來繪製的座標在地圖上和懸停時啓用彈出的代碼。我從這個問題的答案中得到了on_move事件的代碼:Matplotlib basemap: Popup box 希望這有助於。

+0

對此有一個解釋是很好的,至於爲什麼我們應該寫這樣的代碼,而不是粘貼代碼並說你從某個地方得到它。如果他們將來會回答您的問題,這也會幫助其他人。 – rsz

+0

@rsz對不起。編輯。 – samuelv