Pythonでグラフ1から任意範囲を抜き取ってグラフ2として表示する
画像の輝度プロファイルを読み込んでグラフ表示し、そこから必要な部分(解析にかけたい部分)をグラフ上で選択することを想定。その前段、というか練習として、Sin波をプロットし、そこから任意の区間をマウスクリックで設定し、該当する区間のCos波を表示するプログラム。
結果
上段グラフがSin波。赤線部が選択した部分。下段グラフが抽出されたCos波。
プログラム
Python 3.8.1
Matplotlib 3.1.2
import numpy as np from matplotlib import pylab as plt #def onclick文内if else分岐の状態の初期値を宣言する。 #defの外で値を設定し、かつ、defの中でglobal変数として再度宣言する。 st = 1 #プロットするデータ。テスト用にSinとCosを使う。 #Sinグラフ上で任意区間を設定し、その区間のCosグラフを表示する。 x = np.arange(0, 10, 0.01) y1 = np.sin(x) y2 = np.cos(x) #2段表示のグラフを定義。 fig = plt.figure() ax1 = fig.add_subplot(211) ax2 = fig.add_subplot(212) #上段のグラフにy1を描画する。 ax1.plot(x, y1) fig.show() #グラフをクリックしたときの挙動を定義する。 def onclick(event): #st,leftind,rightindをglobal変数として宣言する。 global st, leftind, rightind #デバッグ用:クリックした位置の情報をprintする。 #print('button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %(event.button, event.x, event.y, event.xdata, event.ydata)) #クリックした位置から近いxの値をind変数に代入する。 ind = np.searchsorted(x, event.xdata) #任意区間の左端選択。クリックした位置を赤丸でプロット。 if event.button == 3 and st == 1: leftind = ind ax1.plot(x[ind], y1[ind], "ro") st = 2 print("任意区間の左端が選択されました。右端を右クリックで選択してください。") #任意区間の右端選択。クリックした位置を赤丸でプロット。区間を赤線表示。 elif event.button == 3 and st == 2: rightind = ind ax1.plot(x[ind], y1[ind], "ro") ax1.plot(x[leftind:rightind +1], y1[leftind:rightind + 1], "r") st = 3 print("任意区間の右端が選択されました。左ダブルクリックで確定してください。") #任意区間を確定する。当該区間のy2を下段のグラフに描画する。 elif event.button == 1 and event.dblclick == 1 and st == 3: ax2.plot(x[leftind:rightind +1], y2[leftind:rightind + 1], "g") st = 4 print("任意区間を決定しました。") #キャンセル。y1とy2のグラフをクリア。y1を再描画する。どの状態かでも実行可能。 elif event.button == 2: ax1.cla() ax2.cla() ax1.plot(x, y1) st = 1 print("キャンセルしました。任意区間の左端を右クリックで選択してください。") #fig.show()との違いがわからない… fig.canvas.draw() #イベントとonclickの紐づけ fig.canvas.mpl_connect('button_press_event', onclick)
[03_ExtractDataFromChart_001.py]
諦めた機能
canvas.restore_region()
の使い方がわからなかった。上のプログラムでは馬鹿正直にグラフクリアして再度描画させている。スマートなコードを描くためにも習得しておきたいが…今回は見送る。