前提・実現したいこと
読み込んだcsvファイルのグラフをmatplotlibを使用してtkinter上に表示させ、その表示させたcanvas上において、右クリックで二点間の範囲を選択し、真ん中クリックでキャンセル、左ダブルクリックで決定して最小二乗法の線を引くプログラムを作成したいと考えております。
発生している問題・エラーメッセージ
読み込んだcsvファイルをcanvasに表示させることはできましたが、canvas内でマウス操作をすることができなくて悩んでおります。
該当のソースコード
Python
1from tkinter import * 2from matplotlib import pyplot as plt 3from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg 4import numpy as np 5from scipy import optimize 6import pylab 7import turtle 8import tkinter as tk 9 10x_data = [] 11y_data = [] 12state = 0 13f = open('xrr_data.csv', 'r') 14 15datalist = f.readlines() 16for data in datalist: 17 if state == 1: 18 x_data.append(float(data.split(',')[0])) 19 y_data.append(float(data.split(',')[1])) 20 if "Angle,Intensity" in data: 21 state =1 22 23f.close() 24xdata = np.array(x_data) 25ydata = np.array(y_data) 26 27def drawlsm(lind,rind): 28 29 global xdata2 30 global ydata2 31 32 xdata2 = xdata[lind:rind] 33 ydata2 = ydata[lind:rind] 34 35 parameter0 = [0.,0.] 36 result = optimize.leastsq(fit_func,parameter0,args=(xdata2,ydata2)) 37 print(result) 38 a_fit=result[0][0] 39 b_fit=result[0][1] 40 print(a_fit,b_fit) 41 plt.plot(xdata,a_fit*xdata+b_fit,'k-', label='fitted line', linewidth=3, alpha=0.3) 42 43 44 45#Least squares method with scipy.optimize 46def fit_func(parameter,x,y): 47 a = parameter[0] 48 b = parameter[1] 49 residual = y-(a*x+b) 50 return residual 51 52def oncmask(event): 53 54 global stat 55 global leftind, rightind 56 57 ind=np.searchsorted(xdata,event.xdata) 58 plt.title("You clicked index="+str(ind)) 59 if event.button==3 and stat==1: 60 leftind=ind 61 ax.plot([xdata[ind]],[ydata[ind]],".",color="red") 62 stat=2 63 elif event.button==3 and stat==2: 64 rightind=ind 65 ax.plot(xdata[leftind:rightind],ydata[leftind:rightind],color="red") 66 stat=3 67 print (leftind, rightind) 68 elif event.button==1 and event.dblclick==1 and stat==3: 69 plt.title("Approved") 70 mask[leftind:rightind]=False 71 drawlsm(leftind,rightind) 72 stat=1 73 elif event.button==2 and stat==3: 74 plt.title("Canceled") 75 ax.plot(xdata[leftind:rightind],ydata[leftind:rightind],color="blue") 76 ax.plot([xdata[leftind]],[ydata[leftind]],".",color="green") 77 stat=1 78 fig.canvas.draw() 79 80mask=np.ones(len(xdata),dtype=bool) 81 82stat = 1 83fig=plt.figure() 84ax=fig.add_subplot(111) 85ax.plot(xdata,ydata) 86 87cid = fig.canvas.mpl_connect('button_press_event', oncmask) 88 89# Windowの設定 90root = Tk() 91root.title("Plot window") 92root.geometry() 93 94 95# Frameの設定 96frame_1 = Frame(root, bd=4, relief=GROOVE) 97frame_2 = Frame(root, bd=4, relief=GROOVE) 98 99# widgetの設定 100canvas = FigureCanvasTkAgg(fig, frame_2) 101 102# widgetの配置 103frame_1.grid(row=0, column=0, sticky=W + E) 104frame_2.grid(row=1, column=0) 105canvas.get_tk_widget().grid(row=0, column=0) 106 107root.mainloop()
試したこと
以下のメソッドで
fig.canvas.mpl_connect('button_press_event', oncmask)
tkinterのウィンドウにグラフを乗せることはできたのですが、
そのグラフにマウスクリックを行っても何も反応がありませんでした。
補足情報(FW/ツールのバージョンなど)
python初心者で至らない点が多々あると思いますが、アドバイス頂けると嬉しいです。
よろしくお願いします。
プログラムを動かした際の画像を添付します。
現在は通常のmatplotlibで出力した際にでてくるグラフ(画面右)にクリックなどの操作を行い、それがtkinter側のグラフ(画面左)に反映されるという形になっております。
![]
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/10/21 07:21