单击 pcolormesh 正方形的中心时使用 matplotlib 选择事件触发?
Posted
技术标签:
【中文标题】单击 pcolormesh 正方形的中心时使用 matplotlib 选择事件触发?【英文标题】:Use matplotlib pick event to trigger when center of pcolormesh squares are clicked? 【发布时间】:2017-05-15 12:46:43 【问题描述】:我正在从事一个更广泛的项目,但在使用带有 pcolormesh 的 matplotlibs picker=True
和 pick_event
时遇到了问题。它有效,但不直观,因为仅当我沿热图“框”的边缘单击时才会触发选择事件,并且它返回周围的索引(因此,如果您单击一个角,则 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()
这是对此处发现的问题的进一步说明:Can matplotlib pick_event return array indeces rather than values or pixels?。我想避免尝试绘制一个被 pcolormesh 掩盖的底层散点图,但如果可能的话会处理选择器事件,因为我觉得必须有一种更简单的方法来实现所需的结果。
【问题讨论】:
【参考方案1】:我建议在这里使用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()
【讨论】:
啊哈,谢谢,button_press_event
太完美了!我仍然更喜欢使用 pcolormesh,因为我使用了 .set_bad()
和其他 pcolormesh 特定的(据我所知)功能。我知道使用 imshow 仍然可以进行类似的操作,但是在我刚刚测试过的情况下更改 IMO 没有任何意义,并且您的修复适用于 pcolormesh,因为我得到了返回的坐标,并且可以轻松地将其转换回我需要的坐标。
是的,所以区别只是在 pcolormesh 中坐标偏移了 0.5,您需要考虑到这一点。
啊,是的,imshow 坐标系统也以 (0,0) 开头,位于图的左上角与左下角,但在任何一种情况下都不难修改。
imshow
从-0.5
开始,因为0
是第一个像素的中心。这肯定很容易适应。以上是关于单击 pcolormesh 正方形的中心时使用 matplotlib 选择事件触发?的主要内容,如果未能解决你的问题,请参考以下文章
Matplotlib:如何使用大型数据集为pcolormesh设置动画
如何在 PyQt5 GUI python 中单击按钮时绘制方形图