2012-09-25 22 views
6

Obecnie używam tego kodu, aby wyświetlać adnotacje na mapie po kliknięciu punktu na mapie bazowej Matplotlib.Python i Matplotlib i adnotacje z Myszem Hover

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() 

Co Zastanawiam się, jest to, jak pokazują adnotacje używając najedź myszką zamiast klikając na punkt?

Widziałem "motion_notify_event", ale wygląda na to, że kod dostaje błędy, gdy poruszam myszką po obszarze wykresu. Jakieś pomysły?

Odpowiedz

8

Spójrz na this question i demo:

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

Widziałem oba te linki, jednak nie jestem pewien, jak je wdrożyć w moim obecnym formacie. nie widzę również, jak "pick_event" jest nie klikalnym działaniem? – mcfly

+6

Przyjmuję tę odpowiedź, ale nie jest to właściwa odpowiedź. Jednak Root powiązał inne pytanie, które łączyło to [pytanie] (http://stackoverflow.com/questions/4453143/point-and-line-tooltips-in-matplotlib/4620352#4620352), które daje prawidłowy sposób na najechanie kursorem i wyświetlenie adnotacje. Uwaga: nadal używam adnotacji zamiast wx.tooltip. Pracuje bardzo dobrze! – 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() 

Oto kod do wykreślenia współrzędnych na mapie i włączyć okienko podczas zawisu. Dostałem kod dla zdarzenia on_move z odpowiedzi na to pytanie: Matplotlib basemap: Popup box Mam nadzieję, że to pomoże.

+0

Byłoby miło mieć wyjaśnienie tego, dlaczego powinniśmy napisać kod taki jak ten, a nie tylko wkleić kod i powiedzieć, że masz go gdzieś. Pomoże to również innym, jeśli dojdą do Twojej odpowiedzi w przyszłości. – rsz

+0

@rsz przepraszam. Edytowane. – samuelv