我正在尝试为matplotlib中的绘图编写一个点选择器。我想告诉我我点击的绘制数组的i,j个独立性。似乎唯一的选择是event.mouseevent.xdata,它是根据绘制的坐标值,或event.mouseevent.x,它是以像素为单位(从我可以看到“像素”不是与网格框相同,即我正在寻找的东西。
我误解了xdata / x是什么。有没有办法做我想做的事。
由于 尼尔
编辑:点击的图像是2D阵列图,例如使用pcolormesh
答案 0 :(得分:1)
event.ind[0]
属性获取索引。进一步的文件here。示例如下:
from numpy import linspace
from numpy import cos
from numpy import pi
import matplotlib.pyplot as plt
x = linspace(0,1,100)
y = cos(x*8*pi) # your array
fig = plt.figure()
ax = fig.add_subplot(111)
line, = ax.plot(x, y, 'b',picker=10)
def onpick(event):
if event.artist!=line: #check that you clicked on the object you wanted
return True
if not len(event.ind): #check the index is valid
return True
ind = event.ind[0]
ax.plot(x[ind],y[ind],'ro')
fig.canvas.draw()
return True
fig.canvas.mpl_connect('pick_event', onpick)
fig.show()
编辑:好的。然后,您可以先在网格点上绘制一条线,然后在上方绘制pcolormesh对象,并隐藏该线。这是代码
x = linspace(0,9,10)+.5
y = linspace(0,9,10)+.5 # your array
x,y=meshgrid(x,y)
x=x.flatten()
y=y.flatten()
fig = plt.figure()
ax = fig.add_subplot(111)
line, = ax.plot(x, y, 'b',picker=10)
line.set_visible(False)
ax.pcolormesh(np.random.randn(10,10))
def onpick(event):
if event.artist!=line: #check that you clicked on the object you wanted
return True
if not len(event.ind): #check the index is valid
return True
ind = event.ind[0]
ax.plot(x[ind],y[ind],'ro')
fig.canvas.draw()
return True
fig.canvas.mpl_connect('pick_event', onpick)
fig.show()
答案 1 :(得分:0)
我遇到了类似的问题,并让它发挥作用。首先,如果您发布一些示例代码,它会很有帮助。这是我用来更新嵌入式图表的另一个例子,但我不得不添加一个选择器。我现在遇到的问题是,对于pcolormesh,只有当你点击边框时才会返回选择器(gg349在技术上解决了这个问题......但很难实现IMO)。如果您运行以下代码并单击绘图按钮并单击单元格边框,您可以看到我如何返回“数据”点(在这种情况下只是标签索引,但是您得到了jist:
In [1]
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
#import matplotlib.animation as animation
#from matplotlib import style
import numpy as np
import Tkinter as tk
import ttk
def customplot(f,X):
try:
f.clf()
except:
None
try:
ax=ax
except:
ax=f.add_subplot(111)
ax.pcolormesh(X,picker=True)
ax.set_yticks(arange(0.5,len(X)+0.5))
ax.set_xticks(arange(0.5,len(X)+0.5))
ax.set_yticklabels(["LabY"+str(l) for l in range(len(X))])
ax.set_xticklabels(["LabX"+str(l) for l in range(len(X))])
class My_GUI:
def __init__(self,master):
self.master=master
self.f = Figure(figsize=(5,5), dpi=100)
self.canvas1=FigureCanvasTkAgg(self.f,self.master)
self.updatechartbutton=tk.Button(master=master,text='update plot',command=self.drawcustomplot)
self.canvas1.get_tk_widget().pack(side="top",fill='x',expand=True)
self.canvas1.mpl_connect('pick_event',self.onpick)
self.toolbar=NavigationToolbar2TkAgg(self.canvas1,master)
self.toolbar.update()
self.toolbar.pack(side='top',fill='x')
self.updatechartbutton.pack(side='top')
def drawcustomplot(self):
self.X=array(np.random.normal(size=[3,3]))
customplot(self.f,self.X)
#plt.xticks([1,2,3],['one','two','three'])
self.canvas1.show()
def onpick(self,event):
print('Returned indices')
print(event.ind)
print('mapping back:')
self.myxlabels=["LabX"+str(l) for l in range(len(self.X))]
self.myylabels=["LabY"+str(l) for l in range(len(self.X))]
self.ypos=event.ind[0] / 3
self.xpos=event.ind[0] % 3
print("Y: "+str(self.myylabels[self.ypos])+' X:'+str(self.myxlabels[self.xpos]))
root=tk.Tk()
gui=My_GUI(root)
root.mainloop()
并且当您单击时,您可以看到它返回索引,然后是我重新映射的点:
Out [1]
Returned indices
[2]
mapping back:
Y: LabY0 X:LabX2
Returned indices
[1]
mapping back:
Y: LabY0 X:LabX1
Returned indices
[7]
mapping back:
Y: LabY2 X:LabX1
Returned indices
[8]
mapping back:
Y: LabY2 X:LabX2
Returned indices
[5 8]
mapping back:
Y: LabY1 X:LabX2
例如,在我的最后一次点击中,我点击了中右和右上角之间的边界,返回索引[5 8](第5个方框和第8个方框从左下方向右上方沿行排列在这里我总是说取第一个索引(所以如果你点击你想要它的顶部会返回正确的索引)。所以这里我们正确地返回行Y1和列X2。
我知道这可能不太理想,我仍然在想办法让它成为触发事件的盒子的中心,但至少告诉你如何从返回的索引中获取一些数据来自pcolormesh采摘。
如果我的例子不清楚,这里是我的“最后”点击的可视化。数字是从每个框中的event.ind返回的索引,5左右的红色圆圈表示我的代码找到标签的索引,当我点击黄色圆圈所在的位置时返回。