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

5uzkadbs  于 2023-03-03  发布在  其他
关注(0)|答案(3)|浏览(182)

我尝试在matplotlib中实现一个简单的鼠标点击事件。我希望绘制一个图形,然后使用鼠标选择积分的下限和上限。到目前为止,我能够将坐标打印到屏幕上,但不能将其存储在程序中供以后使用。我还希望在第二次鼠标点击后退出与图形的连接。
下面是当前绘图并打印坐标的代码。

我的问题:

如何将坐标从图形存储到列表中?例如,单击= [xpos,ypos]
有没有可能得到两组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()
zbsbpyhn

zbsbpyhn1#

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

fig.canvas.mpl_disconnect(cid)

以断开事件挂钩。
你要做的事情是这样的:

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 (f'x = {ix}, y = {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)
kmpatx3s

kmpatx3s2#

感谢otterb提供了答案!我在这里添加了一个小函数... Find nearest value in numpy array
在所有这些代码将绘图,等待选择的x点,然后返回指数的x阵列所需的任何积分,求和等。
谢谢

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
vmjh9lq9

vmjh9lq93#

我想在这里提供一个不同的答案,因为我最近尝试做事件处理,但这里的解决方案不区分缩放,平移和点击,一切都搞砸了在我的情况下.我发现一个matplotlib的扩展名为mpl_point_clicker,它真的很适合我,可以安装pip(与python 3.X).以下是他们的文档的基本用法:

import numpy as np
import matplotlib.pyplot as plt
from mpl_point_clicker import clicker

fig, ax = plt.subplots(constrained_layout=True)
ax.plot(np.sin(np.arange(200)/(5*np.pi)))
klicker = clicker(ax, ["event"], markers=["x"])

plt.show()

print(klicker.get_positions())

单击3次后的图和输出如下所示

输出:

{'event': array([[ 24.22415481,   1.00237796],
       [ 74.19892948,  -0.99140661],
       [123.23078387,   1.00237796]])}

相关问题