matplotlib可以选择事件返回数组索引而不是值或像素吗?

时间:2014-02-18 10:37:06

标签: python matplotlib

我正在尝试为matplotlib中的绘图编写一个点选择器。我想告诉我我点击的绘制数组的i,j个独立性。似乎唯一的选择是event.mouseevent.xdata,它是根据绘制的坐标值,或event.mouseevent.x,它是以像素为单位(从我可以看到“像素”不是与网格框相同,即我正在寻找的东西。

我误解了xdata / x是什么。有没有办法做我想做的事。

由于 尼尔

编辑:点击的图像是2D阵列图,例如使用pcolormesh

2 个答案:

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

enter image description here

编辑:好的。然后,您可以先在网格点上绘制一条线,然后在上方绘制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()

enter image description here

答案 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左右的红色圆圈表示我的代码找到标签的索引,当我点击黄色圆圈所在的位置时返回。 enter image description here