pythonでシリアルポートに流れてくる測定データを取得し、それをグラフにプロットしていくアプリを作っています。
グラフやUIはtkinterとmatplotlibで作っています。
グラフを描画しようとするとアプリ自体が終了してしまいます。どのようにすればいいでしょうか?
当方の環境は
windows10 64bit + anaconda + vscodeで行っています。
それぞれのバージョンは、
・Windows10 64bit ver1909 build18363.815
・anaconda ver1.7.2
・python ver 3.7.7
になります。
現在、グラフ描画以外はうまく動いていそうなので、グラフ描画だけ切り出して下記のコードで動作テストをしています。
python
1canvas.get_tk_widget().grid( row = 0, column = 0)
を入れると、
Fatal Python error: PyEval_RestoreThread: NULL tstate
というエラーが出て、プログラムが終了します。ここをコメントアウトすると、プログラムは落ちませんが、グラフは表示されません。
私の理解では、この問題の行で、グラフをGUIのどのエリアにどのくらいのサイズで描画するのか設定するのですが、どのように設定すればいいのか分かりません。
python
1import sys 2import time 3import numpy as np 4import tkinter 5import random 6from tkinter import ttk 7import matplotlib.pyplot as plt 8import matplotlib.animation as animation 9from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg 10 11class ChartData(): 12 def __init__( self, series:int): 13 self.MAT_SIZE = 100 # matrix size 14 15 self.count = 0 # packet counter 16 self.x_data = np.zeros( self.MAT_SIZE) # x-axis data 17 self.y_data = np.zeros( ( series, self.MAT_SIZE)) # y-axis data 18 self.lines = [] # chart lines 19 20# @brief update combobox 21# @param event event handler 22def UpdatePortCombo( event): 23 print( cb_port_val.get()) 24 25# @brief quit program 26def Quit(): 27 # terminate serial receive thread 28 root.destroy() 29 30# @brief open serial port 31def OpenPort(): 32 return True 33 34# @brief close serial port 35def ClosePort(): 36 return True 37 38# @brief main function 39if __name__ == '__main__': 40 series = 6 # data series 41 packet_size = 4 * ( 6 + 1) # packet size 42 43 # initialize GUI object 44 root = tkinter.Tk() 45 root.title( 'CQ ARM First Telemetory') 46 47 cb_port_val = tkinter.StringVar() 48 cd = ChartData( series = series) 49 50 """ GUI parts draw part """ 51 dbg = ['aaa', 'bbb'] 52 # serial port select combobox 53 cb_port = ttk.Combobox( values = dbg, textvariable = cb_port_val, width = 7) 54 cb_port.bind( '<<ComboboxSelected>>', UpdatePortCombo) 55 cb_port.current( 0) 56 cb_port.grid( row = 1, column = 1, columnspan = 2) 57 58 # open serial port & monitor start button 59 btn_open = tkinter.Button( text = 'Open Port', width = 10, command = OpenPort) 60 btn_open.grid( row = 2, column = 1, columnspan = 2) 61 62 # close serial port & monitor stop button 63 btn_close = tkinter.Button( text = 'Close Port', width = 10, command = ClosePort) 64 btn_close.grid( row = 3, column = 1, columnspan = 2) 65 66 # quit app button 67 btn_quit = tkinter.Button( text = 'Quit', width = 10, command = Quit) 68 btn_quit.grid( row = 4, column = 1, columnspan = 2) 69 70 """ chart draw part """ 71 # create chart base 72 fig, axes = plt.subplots( 2, 1) 73 canvas = FigureCanvasTkAgg( fig, master = root) 74 canvas.get_tk_widget().grid( row = 0, column = 0) 75 76 axes[0].set_xlabel( 'time') 77 axes[0].set_ylabel( 'acceleration[mm/s^2]') 78 axes[0].set_title( 'time - acceleration chart') 79 axes[0].grid() 80 line_x, = axes[0].plot( cd.x_data, cd.y_data[0], color = "red", label = 'x') 81 line_y, = axes[0].plot( cd.x_data, cd.y_data[1], color = "green", label = 'y') 82 line_z, = axes[0].plot( cd.x_data, cd.y_data[2], color = "blue", label = 'z') 83 cd.lines.append( line_x) 84 cd.lines.append( line_y) 85 cd.lines.append( line_z) 86 87 axes[1].set_xlabel( 'time') 88 axes[1].set_ylabel( 'angular velocity[mdeg/s]') 89 axes[1].set_title( 'time - angular velocity chart') 90 axes[1].grid() 91 line_x, = axes[1].plot( cd.x_data, cd.y_data[3], color = "red", label = 'x') 92 line_y, = axes[1].plot( cd.x_data, cd.y_data[4], color = "green", label = 'y') 93 line_z, = axes[1].plot( cd.x_data, cd.y_data[5], color = "blue", label = 'z') 94 cd.lines.append( line_x) 95 cd.lines.append( line_y) 96 cd.lines.append( line_z) 97 98 # @biref run chart 99 def run( ii): 100 """ 101 xx_data = [cd.x_data[-1] + 1] 102 yy_data = [[random.random(),random.random(),random.random(),random.random(),random.random(),random.random()]] 103 cd.x_data = np.roll( cd.x_data, shift = -1) 104 cd.y_data = np.roll( cd.y_data, shift = -1, axis = 1) 105 cd.x_data[-1] = xx_data[0] 106 cd.y_data[:,-1] = yy_data[0] 107 108 for i in range( 6): 109 cd.lines[i].set_data( cd.x_data, cd.y_data[i]) 110 111 return cd.lines, 112 """ 113 print( ii) 114 115 anime = animation.FuncAnimation( fig, run, interval = 500, blit = False) 116 plt.draw() 117 118 # app start 119 root.mainloop() 120 121 exit(0) 122
回答1件
あなたの回答
tips
プレビュー