单击 pcolormesh 正方形的中心时使用 matplotlib pick 事件触发?

Use matplotlib pick event to trigger when center of pcolormesh squares are clicked?

我正在从事一个更广泛的项目,但是 运行 遇到了使用 matplotlibs picker=Truepick_event 以及 pcolormesh 的问题。它有效,但不直观,因为仅当我沿着热图 'boxes' 的边缘单击时才会触发拾取事件,并且它 return 是周围的索引(因此,如果单击一个角,则 4 个索引是return由 4 个框在该点的交集计算得出。

例如,在下图中,当我在黄色圆圈附近单击时,我的选择器 returns 索引 [5 8](5 是下面的框,8 是上面的框)。相反,我想 return 仅在单击 'box' 时索引 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()

这是对此处发现的问题的补充:Can matplotlib pick_event return array indeces rather than values or pixels?。我想避免尝试绘制被 pcolormesh 掩盖的底层散点图,但如果可能的话会处理选择器事件,因为我觉得必须有一种更简单的方法来实现所需的结果。

我建议在这里使用 button_press_event。从中您可以轻松获得单击像素的坐标。在 imshow 情节的情况下,它更容易,

x = int(np.round(event.xdata))
y = int(np.round(event.ydata))

完整示例(使用imshow):

import numpy as np
import matplotlib.pyplot as plt

X=np.array(np.random.normal(size=[3,3]))

myxlabels=["LabX"+str(l) for l in range(len(X[0,:]))]
myylabels=["LabY"+str(l) for l in range(len(X))]
plt.imshow(X)
plt.xticks(range(len(X[0,:])),myxlabels )
plt.yticks(range(len(X)),myylabels )

def onclick(event):
    print('Returned indices')
    print(event.xdata, event.ydata)
    print('mapping back:')
    x = int(np.round(event.xdata))
    y = int(np.round(event.ydata))
    tx = "Y: {}, X: {}, Value: {:.2f}".format(myylabels[y], myxlabels[x], X[y,x])
    print(tx)

plt.gcf().canvas.mpl_connect('button_press_event', onclick)

plt.show()