変化するデータファイルをリアルタイムにプロットするスクリプト
シミュレーションなどでデータをファイルに出力する際,リアルタイムにデータをプロットしたい場合がある.gnuplot を popen し,自動的に replot によって描画を更新する python スクリプトを作ってみた.
itplot
os.popen でプロセスを開いて,write メソッドで書き込み,flush メソッドでフラッシュする.前半はコマンドラインオプションのパース.
#!/usr/bin/python import os,time,sys usage='''iterative graph plotter using gnuplot usage: itplot [OPTION] PLOTLINE OPTION: -s XXX setting line -i T iteration interval (second) -help show help example: itplot hoge.dat using 3:4 itplot -s 'set xrange [-1.5:1.5];set yrange [-1.5:1.5]' hoge.dat itplot '"< tail -100 trajectory.dat"' u 1:3 w lp''' # default setting: setting='set key right bottom' setting=setting+'; min(x,y)=x<=y?x:y; max(x,y)=x>=y?x:y' pline='' tsleep=1.0 it= iter(sys.argv) it.next() # skip exec name while True: try: a= it.next() if a=='-help' or a=='--help': print usage; sys.exit(0) elif a=='-s': setting=setting+'; '+it.next() elif a=='-i': tsleep=float(it.next()) elif os.path.exists(a): pline=pline+' "'+a+'"' else: pline=pline+' '+a except StopIteration: break print 'plot '+pline g= os.popen('gnuplot -noraise','w') g.write(setting+'\n') g.write('plot '+pline+'\n') g.flush() try: while True: g.write("replot\n") g.flush() time.sleep(tsleep) except KeyboardInterrupt: g.close()
使い方
itplot -i 0.1 out.dat w l
とすれば,out.dat を直線で (w l) プロットし,0.1秒ごとに更新しつづける."out.dat w l" は gnuplot に直接送られるので(ただしファイル名はクォートされる),
itplot -i 0.1 out.dat u 1:3 w l, out.dat u 1:4 w lp
みたいなこともできる(out.dat の1:3行を直線でプロット,out.datの1:4行を点と直線でプロット).
out.dat がリアルタイムに更新されるファイルなら,自動的にグラフが更新されて行く.
itplot -s 'set xrange [-1:1]' -i 0.1 out.dat w l
こうすると,x方向のプロット範囲が[-1:1]で固定される.-s '...' で指定したものは,gnuplot の plot コマンド以前に実行される.
なお,終了はCtrl+Cで.
例:リサージュ
C++ でリサージュカーブをデータで出力するプログラムを書き,それをリアルタイムに描画してみる.
#include <fstream> #include <cmath> #include <unistd.h> using namespace std; int main(int argc, char**argv) { ofstream ofs("out.dat"); for (double t(0.0);t<10000.0;t+=0.01) { ofs<<cos(M_PI*t)<<" "<<sin(2.0*M_PI*t)<<endl; usleep(10000); } return 0; }
こんな感じで書いて保存,実行.
別の端末を開いて,同じディレクトリで
itplot -i 0.1 -s 'set xrange [-1.2:1.2]; set yrange [-1.2:1.2]' out.dat w l lt 3
と実行すると,リサージュ曲線がプロットされる.
でも,これだと2周目以降はカーブが重なってしまうので,
itplot -i 0.1 -s 'set xrange [-1.2:1.2]; set yrange [-1.2:1.2]' '"< tail -40 out.dat"' w l lt 3
のようにして,out.dat の最後の40行だけ抽出し,プロットする.すると,オシロスコープでリサージュを観察してるような感じになる.