web-dev-qa-db-ja.com

matplotlibでマウスクリックイベントの座標を保存する

Matplotlibで単純なマウスクリックイベントを実装しようとしています。図をプロットしてから、マウスを使用して積分の下限と上限を選択します。これまでのところ、座標を画面に印刷することはできますが、後でプログラムで使用するために座標を保存することはできません。また、2回目のマウスクリック後にFigureへの接続を終了したいと思います。

以下は、現在座標をプロットしてから印刷するコードです。

私の質問:

フィギュアの座標をリストに保存するにはどうすればよいですか?つまり、クリック= [xpos、ypos]

行のそのセクションで単純な統合を行うために、2つのx座標セットを取得することは可能ですか?

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-10,10)
y = x**2

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y)

def onclick(event):
    global ix, iy
    ix, iy = event.xdata, event.ydata
    print 'x = %d, y = %d'%(
        ix, iy)

    global coords
    coords = [ix, iy]

    return coords


for i in xrange(0,1):

    cid = fig.canvas.mpl_connect('button_press_event', onclick)


plt.show()
25
smashbro

イベントをイベントハンドラーに接続するには、mpl_connectを一度だけ呼び出す必要があります。切断するまで、クリックイベントのリッスンを開始します。使用できます

fig.canvas.mpl_disconnect(cid)

イベントフックを切断します。

あなたがしたいことは次のようなものです:

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-10,10)
y = x**2

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y)

coords = []

def onclick(event):
    global ix, iy
    ix, iy = event.xdata, event.ydata
    print 'x = %d, y = %d'%(
        ix, iy)

    global coords
    coords.append((ix, iy))

    if len(coords) == 2:
        fig.canvas.mpl_disconnect(cid)

    return coords
cid = fig.canvas.mpl_connect('button_press_event', onclick)
29
otterb

答えを提供してくれたotterbに感謝します!ここから取った小さな関数を追加しました... numpy配列の最も近い値を見つける

このすべてのコードでプロットし、xポイントの選択を待ってから、積分、合計などに必要なx配列のインデックスを返します。

Ta、

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import trapz

def find_nearest(array,value):
    idx = (np.abs(array-value)).argmin()
    return array[idx]

# Simple mouse click function to store coordinates
def onclick(event):
    global ix, iy
    ix, iy = event.xdata, event.ydata

    # print 'x = %d, y = %d'%(
    #     ix, iy)

    # assign global variable to access outside of function
    global coords
    coords.append((ix, iy))

    # Disconnect after 2 clicks
    if len(coords) == 2:
        fig.canvas.mpl_disconnect(cid)
        plt.close(1)
    return


x = np.arange(-10,10)
y = x**2

fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(x,y)

coords = []

# Call click func
cid = fig.canvas.mpl_connect('button_press_event', onclick)

plt.show(1)


# limits for integration
ch1 = np.where(x == (find_nearest(x, coords[0][0])))
ch2 = np.where(x == (find_nearest(x, coords[1][0])))

# Calculate integral
y_int = trapz(y[ch1[0][0]:ch2[0][0]], x = x[ch1[0][0]:ch2[0][0]])

print ''
print 'Integral between '+str(coords[0][0])+ ' & ' +str(coords[1][0])
print y_int
6
smashbro