2012-09-25 14 views
6

मैं वर्तमान में इस कोड को मानचित्र पर एनोटेटेशन पॉप अप करने के लिए नियोजित कर रहा हूं जब मैं बेसमैप मैटलप्लॉट प्लॉट में किसी बिंदु पर क्लिक करता हूं।माउस होवर के साथ पाइथन और मैटलप्लिब और एनोटेशन

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 question और 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

मैंने इन दोनों लिंक को देखा है, हालांकि मुझे यकीन नहीं है कि उन्हें अपने वर्तमान प्रारूप में कैसे कार्यान्वित किया जाए। मैं यह भी नहीं देखता कि कैसे "pick_event" एक क्लिक करने योग्य कार्रवाई है? – mcfly

+6

मैं इस उत्तर को स्वीकार कर रहा हूं, लेकिन यह सही जवाब नहीं है। हालांकि, रूट ने एक और प्रश्न पूछा जो इस [प्रश्न] (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

संबंधित मुद्दे