#たくさんのセンサー出力値リアルタイムグラフ化したい
例えば、ジャイロのX,Y,Z 加速度計のX,Y,Z などを同時表示したいと思い
matplotlibをいじっていたのですが、決められたライン数のみしか表示するサンプルしか見つからず、試行錯誤しながら可変数ラインを表示できるリアルタイムグラフ表示を自分で作ってみました。
###使用環境
windows , winpython, numpy, matplotlib
###実行結果
Sin, Cos, Tan計算結果をグラフ表示とは別のスレッドで入力しています。
実際に動作させれば、リアルタイムに動作します
サンプルでは3ラインだけですが、理論的に無限にグラフを増やせるはずです。
###苦労したこと
Pythonのタプルをちゃんと理解していなかったので、とても時間がかかった。
(今でもちゃんと理解できていないかもしれませんが...)
###ソースコード
Variable_graph.py
import numpy as np
import tkinter as tk
import tkinter.ttk as ttk
import math
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure
import matplotlib.animation as animation
class GraphFrame(ttk.Frame):
def __init__(self, master, graph_num):
#Graph view
fig = Figure()
canvas = FigureCanvasTkAgg(fig, master=master)
self.x = np.arange(0, 10, 0.1)
self.y_datas = []
for y in range(graph_num):
print(y)
self.y_datas.append( np.zeros(100) )
l = np.arange(0, 10, 0.01)
plt = fig.add_subplot(111)
plt.set_ylim([-2, 2])
plt.set_position([0.07, 0.05, 0.9, 0.9])
self.lines = []
for y in range(graph_num):
yp, = plt.plot(self.y_datas[y])
self.lines.append( yp, )
ani = animation.FuncAnimation(fig, self.animate, l,
interval=20, blit=True,
)
canvas.get_tk_widget().pack()
def animate(self, i):
count = 0
for line in self.lines:
line.set_ydata(self.y_datas[count])
count+=1
return self.lines[0:]
def setValues(self, vals):
count = 0
for val in vals:
self.y_datas[count] = np.append(self.y_datas[count], val)
self.y_datas[count] = np.delete(self.y_datas[count], 0)
count+=1
class DataUpdateGraph(ttk.Frame):
def __init__(self, master):
self.test_count = 0
self.graph_num = 3
#Selectable lines
self.master = master
graph_frame = ttk.Frame(master)
self.gf =GraphFrame(graph_frame, self.graph_num)
graph_frame.pack(side = 'right', fill = 'x')
self.update()
def update(self):
vals = []
vals.append( math.sin(math.radians(10*self.test_count)))
vals.append( math.cos(math.radians(10*self.test_count)))
vals.append( math.tan(math.radians(10*self.test_count)))
self.gf.setValues( vals )
self.test_count+=1
self.master.after(100, self.update)
if __name__ == "__main__":
win = tk.Tk()
gh = DataUpdateGraph(win)
win.mainloop()