使用matplotlib存储鼠标单击事件坐标

时间:2021-01-27 21:19:04

I am trying to implement a simple mouse click event in matplotlib. I wish to plot a figure then use the mouse to select the lower and upper limits for integration. So far I am able to print the coordinates to screen but not store them for later use in the program. I would also like to exit the connection to the figure after the second mouse click.

我正在尝试在matplotlib中实现一个简单的鼠标单击事件。我想绘制一个图形,然后用鼠标选择积分的上下限。到目前为止,我可以将坐标打印到屏幕上,但不能将它们存储起来供以后在程序中使用。我还想在鼠标再次点击后退出到图形的连接。

Below is the code which currently plots and then prints the coordinates.

下面是当前绘制并打印坐标的代码。

My Question(s):

我的问题:

How can I store coordinates from the figure to list? i.e. click = [xpos, ypos]

如何从图形到列表存储坐标?即点击= [xpos, ypos]

Is it possible to get two sets of x coordinates in order to do a simple integration over that section of line?

有可能得到两组x坐标来对这段直线进行简单的积分吗?

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

2 个解决方案

#1


18  

mpl_connect needs to be called just once to connect the event to event handler. It will start listening to click event until you disconnect. And you can use

mpl_connect只需调用一次,就可以将事件连接到事件处理程序。它将开始监听单击事件,直到您断开连接。你可以使用

fig.canvas.mpl_disconnect(cid)

to disconnect the event hook.

断开事件挂钩。

What you want to do is something like:

你想做的是:

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)

#2


6  

Thanks to otterb for providing the answer! I've added in a little function taken from here... Find nearest value in numpy array

感谢otterb提供的答案!我添加了一个函数…在numpy数组中找到最接近的值

In all this code will plot, wait for selection of x points and then return the indices of the x array needed for any integration, summations etc.

在所有这些代码中,将绘制,等待x点的选择,然后返回任何集成、求和等所需的x数组的索引。

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

#1


18  

mpl_connect needs to be called just once to connect the event to event handler. It will start listening to click event until you disconnect. And you can use

mpl_connect只需调用一次,就可以将事件连接到事件处理程序。它将开始监听单击事件,直到您断开连接。你可以使用

fig.canvas.mpl_disconnect(cid)

to disconnect the event hook.

断开事件挂钩。

What you want to do is something like:

你想做的是:

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)

#2


6  

Thanks to otterb for providing the answer! I've added in a little function taken from here... Find nearest value in numpy array

感谢otterb提供的答案!我添加了一个函数…在numpy数组中找到最接近的值

In all this code will plot, wait for selection of x points and then return the indices of the x array needed for any integration, summations etc.

在所有这些代码中,将绘制,等待x点的选择,然后返回任何集成、求和等所需的x数组的索引。

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