单击 pcolormesh 正方形的中心时使用 matplotlib pick 事件触发?
Use matplotlib pick event to trigger when center of pcolormesh squares are clicked?
我正在从事一个更广泛的项目,但是 运行 遇到了使用 matplotlibs picker=True
和 pick_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()
我正在从事一个更广泛的项目,但是 运行 遇到了使用 matplotlibs picker=True
和 pick_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()