Python 单击pcolormesh正方形的中心时,是否使用matplotlib拾取事件触发?

Python 单击pcolormesh正方形的中心时,是否使用matplotlib拾取事件触发?,python,matplotlib,picker,tkinter-canvas,Python,Matplotlib,Picker,Tkinter Canvas,我正在处理一个更广泛的项目,但在使用matplotlibspicker=True和带有pcolormesh的pick_事件时遇到了一个问题。它可以工作,但不是直观的,因为拾取事件仅在我沿着热图“框”的边缘单击时触发,并且它返回周围的索引(因此,如果单击某个角点,4个索引将由4个框在该点的交点返回) 例如,在下图中,当我在黄色圆圈附近单击时,我的选择器返回索引[5 8](5是下面的框,8是上面的框)。相反,我只想在单击该“框”时返回索引5。 以下是我用来举例说明我的问题的代码: import m

我正在处理一个更广泛的项目,但在使用matplotlibs
picker=True
和带有pcolormesh的
pick_事件时遇到了一个问题。它可以工作,但不是直观的,因为拾取事件仅在我沿着热图“框”的边缘单击时触发,并且它返回周围的索引(因此,如果单击某个角点,4个索引将由4个框在该点的交点返回)

例如,在下图中,当我在黄色圆圈附近单击时,我的选择器返回索引[5 8](5是下面的框,8是上面的框)。相反,我只想在单击该“框”时返回索引5。

以下是我用来举例说明我的问题的代码:

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

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

这是进一步的问题,在这里找到:。我不想试图绘制被pcolormesh掩盖的底层散点图,但如果可能,我会处理选择器事件,因为我觉得必须有一种更简单的方法来实现所需的结果。

我建议在这里使用
按钮\u press\u事件。从中可以轻松获得单击像素的坐标。在
imshow
绘图的情况下更容易

x = int(np.round(event.xdata))
y = int(np.round(event.ydata))
完整示例(使用
imshow
):


我建议在这里使用
按钮\u press\u事件
。从中可以轻松获得单击像素的坐标。在
imshow
绘图的情况下更容易

x = int(np.round(event.xdata))
y = int(np.round(event.ydata))
完整示例(使用
imshow
):


啊哈,谢谢,
按钮按下\u事件
太完美了!我仍然更喜欢使用pcolormesh,因为我使用了
.set_bad()
和其他pcolormesh特有的(据我所知)功能。我知道imshow仍然可以做类似的事情,但改变IMO毫无意义,因为我刚刚测试了,你的修复程序可以与pcolormesh一起工作,因为我得到了返回的坐标,并且可以轻松地将其转换回我需要的坐标。是的,所以区别只是在pcolormesh中坐标移动了0.5,您需要考虑到这一点。啊,是的,imshow coord系统从绘图左上角的(0,0)开始与左下角的(0,0)开始,但在任何情况下都不难修改。imshow
-0.5
开始,因为
0
是第一个像素的中心。这当然很容易适应。啊哈,谢谢,
按钮按下事件
非常完美!我仍然更喜欢使用pcolormesh,因为我使用了
.set_bad()
和其他pcolormesh特有的(据我所知)功能。我知道imshow仍然可以做类似的事情,但改变IMO毫无意义,因为我刚刚测试了,你的修复程序可以与pcolormesh一起工作,因为我得到了返回的坐标,并且可以轻松地将其转换回我需要的坐标。是的,所以区别只是在pcolormesh中坐标移动了0.5,您需要考虑到这一点。啊,是的,imshow coord系统从绘图左上角的(0,0)开始与左下角的(0,0)开始,但在任何情况下都不难修改。imshow
-0.5
开始,因为
0
是第一个像素的中心。这当然很容易适应。