2017-05-15 11 views
0

私は広範なプロジェクトに取り組んでいますが、matplotlibs picker=Truepick_eventをpcolormeshで使用して問題に取り掛かりました。それは動作しますが、ピックイベントはヒートマップ 'ボックス'の端に沿ってクリックするとトリガされ、周囲のインデックスを返します(コーナーをクリックすると、4つのインデックスが交差点によって返されます)その時点のボックス)。pcolormeshの四角形の中心がクリックされたときにトリガするには、matplotlib pickイベントを使用しますか?

たとえば、次の画像で黄色の円の近くをクリックすると、ピッカーはインデックス[5 8]を返します(5は下のボックスと8です)。代わりに、私はその 'ボックス'がクリックされたときにインデックス5のみを返したいと思います。ここで pcolormesh picker

私は私の問題を例示するために使用されるコードは次のとおりです。

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

なるほど、button_press_event'は完璧だった '、ありがとうございました!私は '.set_bad()'と他のpcolormesh特有の(私が理解する限り)機能を利用するので、実際にはまだpcolormeshを使用することを好みます。 imshowでも同様のことが可能であることは分かっていますが、IMOを変更するだけの感覚はありません。座標が返され、必要なものに簡単に戻すことができるように、pcolormeshで動作します。 – Vlox

+0

はい、違いはちょうどpcolormeshの座標は0.5にシフトされています。これはあなたが納得する必要があります。 – ImportanceOfBeingErnest

+0

ああ、また、imshow coordシステムはプロットの左上(左下)(0,0)から始まりますが、どちらの場合でも動作するように変更するのは難しくありません。 – Vlox

関連する問題