2012-07-18 13 views

risposta

25

Sì, è possibile grazie al framework di gestione degli eventi di matplotlib. Non sono riuscito a trovare un esempio già scritto che faccia ciò a cui sei particolarmente interessato, quindi ne ho scritto uno (che proporrò per l'inclusione nella sorgente matplotlib).

Vorrei leggere attentamente http://matplotlib.sourceforge.net/users/event_handling.html per capire meglio cosa sta succedendo. Si noti che, anche se suona come la soluzione perfetta, "pick_event" è per i clic del mouse, non per gli eventi di overflow del mouse e in questo caso non funziona.

Il mio codice, che potrebbe essere oggettivato molto bene si dovrebbe desiderare, si presenta come:

import matplotlib.pyplot as plt 

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


points_with_annotation = [] 
for i in range(10): 
    point, = plt.plot(i, i, 'o', markersize=10) 

    annotation = ax.annotate("Mouseover point %s" % i, 
     xy=(i, i), xycoords='data', 
     xytext=(i + 1, i), 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) 
     ) 
    # by default, disable the annotation visibility 
    annotation.set_visible(False) 

    points_with_annotation.append([point, annotation]) 


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

on_move_id = fig.canvas.mpl_connect('motion_notify_event', on_move) 

plt.show() 

Speriamo che tutto dovrebbe essere abbastanza leggibile. Una panoramica di alto livello del codice va:

  • creare un elenco di [Punto, annotazione] coppie, dove per impostazione predefinita l'annotazione non è visibile
  • registrare una funzione, "on_move", di essere chiamato ogni volta Rilevato movimento del mouse
  • La funzione on_move scorre attraverso ogni punto e annotazione, se il mouse si trova su uno dei punti, rende visibile l'annotazione associata, se non lo è, rendila invisibile. (Il metodo contains è documented here)

Screenshot of the result

+0

Ah bella, grazie @pelson per il codice e la spiegazione. Questo significa che non esiste un gestore di eventi diretto per il passaggio del mouse su una posizione nella trama. Deve essere fatto indirettamente. –

+0

No. È possibile accedere alle coordinate xey dell'evento del mouse nella funzione 'on_move'. Da quello puoi fare qualsiasi cosa. Nel mio caso ho esaminato tutti gli artisti e identificato, se presente, la posizione del mouse, ma potrei anche aggiornare la posizione di una singola istanza di annotazione data la x e y. – pelson

+0

Sì, hai ragione su questo punto, ma stavo cercando qualcosa come registrare un callback per un artista particolare con un evento come "hover_event" Questo è ciò che intendo per un evento diretto –

Problemi correlati