sma*_*bro 26 python matplotlib onclick mouseevent
我试图在matplotlib中实现一个简单的鼠标单击事件.我希望绘制一个图,然后使用鼠标选择集成的下限和上限.到目前为止,我能够将坐标打印到屏幕,但不能存储它们以供以后在程序中使用.我还想在第二次鼠标点击后退出与图形的连接.
下面是当前绘制然后打印坐标的代码.
我的问题:
如何将图中的坐标存储到列表中?即click = [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()
Run Code Online (Sandbox Code Playgroud)
ott*_*erb 32
只需调用mpl_connect一次即可将事件连接到事件处理程序.它将开始侦听单击事件,直到您断开连接.你可以使用
fig.canvas.mpl_disconnect(cid)
Run Code Online (Sandbox Code Playgroud)
断开事件挂钩.
你想做的是:
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)
Run Code Online (Sandbox Code Playgroud)
感谢otterb提供答案!我在这里添加了一个小函数... 在numpy数组中查找最接近的值
在所有这些代码中将绘制,等待选择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
Run Code Online (Sandbox Code Playgroud)
小智 6
我想在这里提供一个不同的答案,因为我最近尝试进行事件处理,但是这里的解决方案不区分缩放、平移和单击,在我的情况下,一切都变得一团糟。我发现了一个名为mpl_point_clicker的 matplotlib 扩展,它非常适合我,并且可以使用 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())
Run Code Online (Sandbox Code Playgroud)
单击 3 次的图和输出如下所示
输出:
{'event': array([[ 24.22415481, 1.00237796],
[ 74.19892948, -0.99140661],
[123.23078387, 1.00237796]])}
Run Code Online (Sandbox Code Playgroud)