最強のコマンドライン グラフ プロット ツール
いちいち Gnuplot を起動してグラフを描画するのが面倒なので,コマンドラインから使える Gnuplot のラッパスクリプトを書いた.変化するデータファイルをリアルタイムにプロットするスクリプトも組み込んだ.とても使いやすいので紹介する.
スクリプト qplot は最後に掲載.
使い方
qplot [オプション] 描画ライン
「描画ライン」はそのまま gnuplot の plot コマンド (or splot) に渡される.つまり,gnuplot の
> plot "hoge.dat" u 1:3 w l, "hoge.dat" u 1:5 w l
に相当するコマンドラインは
qplot "hoge.dat" u 1:3 w l, "hoge.dat" u 1:5 w l
となる.ただし,
- ファイル名の前のコンマは省略できる(自動的に挿入される)
- ファイル名のクォートは省略できる(同上)
ので,
qplot hoge.dat u 1:3 w l hoge.dat u 1:5 w l
と書いてもよい.
オプション
- -s XXX : コマンド XXX を plot コマンドの前に実行する(主に set コマンドを使う).注意: XXX は '' でクォートする必要がある.
- -3d : 3D-plot (splot) コマンドを使う.
- -o FILE : グラフをファイルに書き出す.画面には表示されない.ファイルタイプは拡張子から自動判別される.現在使用可能なのは,png, jpg, svg, eps.
- - : 標準入力から入力されたデータを表す.`qplot - u 1:3 - u 1:5' のように何度でも使える.
- -it : イタレーティブ・モード.変化するファイルを定期的に replot で更新する.Ctrl+C で終了する.
- -i T : イタレーティブ・モードの更新間隔を変更する(秒.デフォルトは1秒).
- -cs YYY : 共通のプロットスタイル (w l など).各ファイル名の直後に自動挿入される.
- -ac : 自動コンマモード.コンマがファイル名の直前に自動的に挿入される.
- -nc : 自動コンマモードをオフにする.
- -help : ヘルプを表示.
オプションの位置は,どこでも構わない.ただし,-cs YYY はその位置以降のファイルにしか適用されない.
例
基本:
qplot hoge.dat using 3:4
表示範囲を変更する:
qplot -s 'set xrange [-1.5:1.5];set yrange [-1.5:1.5]' hoge.dat
qplot out.dat u 1 w l out.dat u 2 w l -o hoge.svg
サインカーブ(データファイルを使わない):
qplot -s 'set xrange [0:10]' 'sin(x)' w p
trajectory.dat の最後の100行をイタレーティブ・モードでプロットする.0.2秒ごとに更新する:
qplot -i 0.2 '"< tail -100 trajectory.dat"' u 1:3 w lp
ほかのコマンドで処理した結果のデータをプロット.1:3行目を使ったプロット,及び1:5行目を使ったプロットを描画する:
(some command) | qplot - u 1:3 w l - u 1:5 w l
すべての test*.dat をプロットする.共通のスタイル w l を使う:
qplot -cs 'w l' test*.dat
スクリプト qplot
#!/usr/bin/python import os,time,sys import subprocess import tempfile usage='''graph plotter using gnuplot usage: qplot [OPTION] PLOTLINE OPTION: -s XXX setting line -3d 3D-plot (splot) -o FILE save graph into FILE; file type is determined by the extension (png,jpg,svg,eps are available) - use std-in as a data file -it iterative plot mode (quit by Ctrl+C) -i T iteration interval (second; default=1.0) -cs YYY common graph style (put after each filename) -ac auto-comma mode (default=True): comma is automatically inserted before each filename -nc disable auto-comma mode -help show help example: qplot hoge.dat using 3:4 qplot -s 'set xrange [-1.5:1.5];set yrange [-1.5:1.5]' hoge.dat qplot -i 0.2 '"< tail -100 trajectory.dat"' u 1:3 w lp (some command) | qplot - u 1:3 w l - u 1:5 w l qplot -ac -cs 'w l' test*.dat''' # default setting: setting='set key right bottom' setting=setting+'; min(x,y)=x<=y?x:y; max(x,y)=x>=y?x:y' iterative=False tsleep=1.0 pline='' plotter='plot' commonstyle='' autocomma=' ,' stdindata='' def ask_yes_no(): if stdindata!='': sys.stdout.write(' (y|n) > n\n') return False while True: sys.stdout.write(' (y|n) > ') ans= sys.stdin.readline().strip() if ans=='y' or ans=='Y': return True elif ans=='n' or ans=='N': return False def add_to_pline(elem,comma): global pline,autocomma if comma and pline!="": pline=pline+autocomma pline=pline+' '+elem 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=='-3d': plotter='splot' elif a=='-s': setting=setting+'; '+it.next() elif a=='-o': filename=it.next() if os.path.exists(filename): print filename+' : already exists. will you overwrite?' if not ask_yes_no(): sys.exit(0) dummy,ext= os.path.splitext(filename) ext= ext.lower() if ext=='.png': setting=setting+'; set terminal png size 800, 640 transparent' elif ext=='.jpg' or ext=='.jpeg': setting=setting+'; set terminal jpeg size 800, 640' elif ext=='.svg': setting=setting+'; set terminal svg size 1200 780 fname "Trebuchet MS" fsize 24' elif ext=='.eps': setting=setting+'; set terminal postscript eps color "Trebuchet MS" 11' else: print 'WARNING: undefined extension. save graph as png...' setting=setting+'; set terminal png size 800, 640 transparent' setting=setting+'; set output "'+filename+'"' elif a=='-it': iterative=True elif a=='-i': tsleep=float(it.next()); iterative=True elif a=='-cs': commonstyle=' '+it.next() elif a=='-ac': autocomma=' ,' elif a=='-nc': autocomma='' elif a=='-': if stdindata=='': dummy,stdindata=tempfile.mkstemp('.dat') pout=open(stdindata,'w+') while(1): line=sys.stdin.readline() if(not line): break pout.write(line) pout.close() add_to_pline('"'+stdindata+'"'+commonstyle,True) elif os.path.exists(a): add_to_pline('"'+a+'"'+commonstyle,True) else: add_to_pline(a,False) except StopIteration: break if pline=='': print usage; sys.exit(0) print plotter+' '+pline if not iterative: g= subprocess.Popen('gnuplot -persist',shell=True,stdin=subprocess.PIPE) else: g= subprocess.Popen('gnuplot -noraise',shell=True,stdin=subprocess.PIPE) g.stdin.write(setting+'\n') g.stdin.write(plotter+' '+pline+'\n') g.stdin.flush() if iterative: try: while True: g.stdin.write("replot\n") g.stdin.flush() time.sleep(tsleep) except KeyboardInterrupt: #g.terminate() # available for python's version >= 2.6 sys.exit(0)