web-dev-qa-db-fra.com

Stocker les coordonnées de l'événement de clic de souris avec matplotlib

J'essaie d'implémenter un simple événement de clic de souris dans matplotlib. Je souhaite tracer une figure, puis utiliser la souris pour sélectionner les limites inférieure et supérieure à intégrer ..__ Jusqu'à présent, je suis en mesure d'imprimer les coordonnées à l'écran sans les stocker pour une utilisation ultérieure dans le programme. Je voudrais aussi quitter la connexion à la figure après le deuxième clic de souris.

Vous trouverez ci-dessous le code qui trace et affiche ensuite les coordonnées.

Mes questions):

Comment puis-je stocker les coordonnées de la figure à la liste? c'est-à-dire click = [xpos, ypos]

Est-il possible d’obtenir deux ensembles de coordonnées x afin de réaliser une intégration simple sur cette section de ligne?

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-10,10)
y = x**2

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y)

def onclick(event):
    global ix, iy
    ix, iy = event.xdata, event.ydata
    print 'x = %d, y = %d'%(
        ix, iy)

    global coords
    coords = [ix, iy]

    return coords


for i in xrange(0,1):

    cid = fig.canvas.mpl_connect('button_press_event', onclick)


plt.show()
20
smashbro

mpl_connect doit être appelé une seule fois pour connecter l'événement au gestionnaire d'événements. Il commencera à écouter l'événement click jusqu'à ce que vous vous déconnectiez. Et vous pouvez utiliser 

fig.canvas.mpl_disconnect(cid)

pour déconnecter le hook d’événement.

Ce que vous voulez faire est quelque chose comme:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-10,10)
y = x**2

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y)

coords = []

def onclick(event):
    global ix, iy
    ix, iy = event.xdata, event.ydata
    print 'x = %d, y = %d'%(
        ix, iy)

    global coords
    coords.append((ix, iy))

    if len(coords) == 2:
        fig.canvas.mpl_disconnect(cid)

    return coords
cid = fig.canvas.mpl_connect('button_press_event', onclick)
21
otterb

Merci à otterb pour cette réponse! J'ai ajouté une petite fonction prise à partir d'ici ... Trouver la valeur la plus proche dans numpy array

Dans tout ce code va tracer, attendre la sélection de x points, puis renvoyer les indices du tableau x nécessaires pour toute intégration, sommation, etc.

Ta,

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import trapz

def find_nearest(array,value):
    idx = (np.abs(array-value)).argmin()
    return array[idx]

# Simple mouse click function to store coordinates
def onclick(event):
    global ix, iy
    ix, iy = event.xdata, event.ydata

    # print 'x = %d, y = %d'%(
    #     ix, iy)

    # assign global variable to access outside of function
    global coords
    coords.append((ix, iy))

    # Disconnect after 2 clicks
    if len(coords) == 2:
        fig.canvas.mpl_disconnect(cid)
        plt.close(1)
    return


x = np.arange(-10,10)
y = x**2

fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(x,y)

coords = []

# Call click func
cid = fig.canvas.mpl_connect('button_press_event', onclick)

plt.show(1)


# limits for integration
ch1 = np.where(x == (find_nearest(x, coords[0][0])))
ch2 = np.where(x == (find_nearest(x, coords[1][0])))

# Calculate integral
y_int = trapz(y[ch1[0][0]:ch2[0][0]], x = x[ch1[0][0]:ch2[0][0]])

print ''
print 'Integral between '+str(coords[0][0])+ ' & ' +str(coords[1][0])
print y_int
6
smashbro

J'ai un besoin similaire, mais ce code ne fonctionne pas pour moi. Je l'ai copié/collé directement (Anaconda 2.7) mais il apparaît que fig.canvas.mpl_connect ('button_press_event', onclick) n'attend jamais l'entrée, ce qui déclenche une erreur dans les appels coords [n] [m] qui le suivent. Suggestions?

> Traceback (most recent call last):
> 
>   File "<ipython-input-5-d074e6221b24>", line 1, in <module>
>     runfile('C:/Users/xxx/Documents/Python/test/untitled0.py', wdir='C:/Users/xxx/Documents/Python/test')
> 
>   File
> "C:\Anaconda2\lib\site-packages\spyder\utils\site\sitecustomize.py",
> line 705, in runfile
>     execfile(filename, namespace)
> 
>   File
> "C:\Anaconda2\lib\site-packages\spyder\utils\site\sitecustomize.py",
> line 87, in execfile
>     exec(compile(scripttext, filename, 'exec'), glob, loc)
> 
>   File "C:/Users/xxx/Documents/Python/test/untitled0.py", line
> 45, in <module>
>     ch1 = np.where(x == (find_nearest(x, coords[0][0])))
> 
> IndexError: list index out of range
0
GroovyGeek