データを標準出力からそのままグラフ化したい
シェル芸に長けた仕事の仕方をしてる人は往々にしてそういう状況に巡り合いますよね?
私はあります。特に環境が整っていない組込系の仕事をしていると。
(それ以外の人は素直にmatplotlib/seabornでもしてください)
なので、標準入力からデータを受け取ってgnuplotからグラフ化までを行うbash(awk)を作りました。
環境
gnuplot 5.4 patchlevel 0
GNU Awk 5.1.0, API: 3.0 (GNU MPFR 4.1.0, GNU MP 6.2.0)
GNU bash, バージョン 4.4.12(3)-release (x86_64-unknown-cygwin)
グラフ表示するウィンドウはx11を指定していますが、環境によって適当に変更してもらえれば良いと思っています。
使い方
とりあえず表示
$ seq 10 | awk '{print $1,$1**2}'
1 1
2 4
3 9
4 16
5 25
6 36
7 49
8 64
9 81
10 100
$ seq 10 | awk '{print $1,$1**2}' | gplt
optionを使う
一応使えるoptionはhelpで表示されるようにしていますが、メモ書き程度なので、なんとなく使ってみてoption内容を理解するようにしてください。
基本的にはoption指定の後ろに数字なりテキストなりを入れて、どんどん設定入力していくようなイメージになります。
$ gplt --help
[x|y|y2]range,[x|y|y2]r -X X : range setting
[x|y|y2]label,[x|y|y2]l X : label text setting
[x|y|y2]tics,[x|y|y2]t X : scale setting
[x|y|y2]format,[x|y|y2]f X : axis decimal digit num. e.g. X=2->1.00
title,t X : graph title
key,k X : w lp key X. legend label
axis : , u X:X axis. y2axis
font X : font size ratio(default 14)
out : png file output
file X : png file name
size X : png iamge pix size ratio(default:640,480)
例
pngファイルに出力する
$ seq 10 | gplt out
$ ls
001.png
fileでファイル名を指定しなければ001.pngからの連番で作成されていきます。
scriptと絡めて使うと便利です。
X軸のレンジを指定する
$ seq 10 | gplt xrange 0 5
複数データを表示し、第二軸に設定する
$ seq 10 | awk '{print $1,$1*2,$1^2}' | gplt , u 1:3 axis
よく使うのはこのあたりです。
最終的なoutputとしてグラフデータを使う場合はlabel/key/title設定とか整形したりします。
$ seq 20 | awk '{print $1,$1*2,$1^2,$1/2}' | gplt w lp pt 5 k data1 , u 1:3 axis k y2axis yr 0 50 y2r 0 500 , u 1:4 w p pt 7 ps 4 k data3 xl xaxis yl yaxis t test_graph
コード
内容のほとんど(引数のoption解析)がawkなのでawkでシンタックスハイライトしています。
長いので折りたたみ
#!/bin/bash
# gnuplot 4.0 upper
# awk gawk 4.0 upper
###############
### setting ###
###############
### X window font size (8,10{11},12{13},14,17,18{20},24{25})
terminal_font_size=14
### default graph size
def_height=640
def_width=480
### deault graph size ratio
graph_size=1.1
### default graph terminal on gnuplot 5.0 over
def_terminal="x11"
# gnuplot version check
gnuplot_ver=`gnuplot -V | awk '{print int($2)}'`
# gnuplot_ver=4 # ver4.0debug
if [ $gnuplot_ver -lt 5 ]; then
# 5未満なら組込PC上(Xwindow無し)の使用
gnuplot4_flag=1
terminal="png"
gnuplotcmd="gnuplot"
else
# 5以上ならローカルPCでXwindow前提の使用
gnuplot4_flag=0
terminal=$def_terminal
gnuplotcmd="gnuplot -p"
fi
# for png font size setting
if [ $terminal = "png" ]; then
term_font_set="giant"
else
term_font_set="font\",$terminal_font_size\""
fi
filename='tmp_01.dat'
optionfile='tmp_02.gp'
waferfile='tmp_03.dat'
displayfile='tmp_04.png'
xlinefile='tmp_05.dat'
ylinefile='tmp_06.dat'
if [ $# -eq 0 ]; then
sed 's/,/ /g' | awk 'substr($1,1,1)!~/#|%/' > $filename
$gnuplotcmd <<EOF
set term $terminal size $def_height*$graph_size,$def_width*$graph_size $term_font_set
set out '$displayfile'
set nokey
set grid
plot '$filename' w lp pt 6
EOF
else
# help disp
if [ $1 = "--help" ] || [ $1 = "--h" ] || [ $1 = "-h" ] || [ $1 = "-help" ] || [ $1 = "help" ]; then
echo "####################"
echo "### graph option ###"
echo "####################"
echo "[x|y|y2|cb][range|r] (min) (max) : range setting. e.g. xr 0 5 -> 0to5"
echo " {abs (absmax)} : range abs setting. e.g. xr abs 100 -> -100to100"
echo "[x|y|y2|cb][label|l] X : label text setting. e.g. xl \"test\""
echo "[x|y|y2|cb][tics|t] X : scale setting. e.g. xt 2->2 4 6..."
echo "[x|y|y2|cb][format|f] X : axis decimal digit num. e.g. xf 2->1.00"
echo "[title|t] X : graph title. If no file name is set and the file is to be output, the title will be used as the file name."
echo "[key|k] X : w lp key X. legend label"
echo "[keypos|kp] [left|l][right|r]"
echo " [top|t][bottom|b] : legend label position e.g. kp r b"
echo "axis : using y2axis e.g. , u X:X axis"
echo "log [x|y|y2|cb] : axis logscale"
echo "font [(3)|(giant|g|2)|(large|l|1)|(medium|m|0)|"
echo " (small|s|-1)|(tiny|t|-2)|(-3)]: font size e.g. font l. e.g. font 2"
echo "size X : png iamge pix size ratio(default:640,480)"
echo "all {no \"keystr\"} : col all data plot. X is key title number. XX is key title str."
echo " {[h|s][s|split]} : vsplit arranges charts vertically. hsplit arrange charts horizon."
echo "[x|y]line X : line plot"
echo "wafer [2|4|6|8|12] : wafer circle [inch]"
echo "bar {rot} {label} : bar graph. rot is xtics dir rot. label is data label."
echo "bubble {scale X} {refoff} : bubble chart. scale is ref chart scale size."
echo "map {gray|viridis} : color map graph u 1:2:3."
echo ""
echo "#####################"
echo "### output option ###"
echo "#####################"
echo "out : png file output"
echo "file X : png file name"
echo "svg : for markdown"
echo "sixel|term|terminal : terminal display"
echo ""
echo "####################"
echo "### other option ###"
echo "####################"
echo "fit {poly X} {txt|text|dat} : poly fitting. degree X. txt is fitting log output \"fit.log\""
echo " {gauss {height} {peak} {sigm} {base}}"
echo " : gauss fitting. "
echo "headder : "
exit;
fi
sed 's/,/ /g' | awk 'substr($1,1,1)!~/#|%/' > $filename
# record number get
nf=`awk 'NR>1{print NF;exit}' $filename`
echo $@ |\
awk '\
function adb(s, n1, n2, n3, n4, n5){return out = sprintf(s, n1, n2, n3, n4, n5) out}
function ad(s, n1, n2, n3, n4, n5){return out = out sprintf(s, n1, n2, n3, n4, n5)}
function adop(s, n1, n2, n3){return w = w sprintf(s, n1, n2, n3)}
function number_judge(x){return x~/^[-+]*[0-9]+\.*[0-9]*$/}
function natural_no_judge(x){return x~/^[+]*[1-9]+[0-9]*$/}
function range_set(s, min_tmp, max_tmp){
min_tmp = max_tmp = ""
if($(i+1)=="abs" && number_judge($(i+2)) && $(i+2)>0){
# arg1 abs -> range
min_tmp = -$(i+2)
max_tmp = $(i+2)
}else{
if(number_judge($(i+1))){
min_tmp = $(i+1)
next_flag++
}
if(number_judge($(i+2))){
max_tmp = $(i+2)
next_flag++
}
}
gsub("range", "", s)
gsub("r", "", s)
ad("set %srange [%s:%s];", s, min_tmp, max_tmp)
}
function tics_set(s){
gsub("tics", "", s);
gsub("t", "", s)
ad("set %stics %s;", s, $(i+1))
}
function label_set(s){
gsub("label", "", s)
gsub("l", "", s)
ad("set %slabel \"%s\"", s, $(i+1));
if(!gnuplot4_flag)ad(" noenhanced")
ad(";")
}
function format_set(s){
gsub("format", "", s)
gsub("f", "", s)
return format[s] = $(i+1)
}
function maxminget( rc, rcr, k, n, i){
if(maxminget_flag)return
i = 0
while(getline rc < filename > 0){
n = split(rc, rcr);
if(!maxminget_flag)for(k=1; k<=nf; k++)mint[k] = maxt[k] = rcr[k]
i++
for(k=1; k<=nf; k++){
data[i, k] = rcr[k];
if(rcr[k]>maxt[k])maxt[k]=rcr[k]
if(rcr[k]<mint[k])mint[k]=rcr[k]
}
maxminget_flag++
}
nr = maxminget_flag
close(filename)
}
function wafer_setting(){
if(out!~/xrange/ && out!~/yrange/)ad("set size square;")
if(out!~/xrange/)ad("set xrange [-%d*1.1:%d*1.1];", wafer_size, wafer_size)
if(out!~/yrange/)ad("set yrange [-%d*1.1:%d*1.1];", wafer_size, wafer_size)
if(out!~/xlabel/)ad("set xlabel \"x[mm]\";")
if(out!~/ylabel/)ad("set ylabel \"y[mm]\";")
ad("wafer_size=%s;", wafer_size)
}
BEGIN{
axis_list["x"]++
axis_list["y"]++
axis_list["y2"]++
axis_list["cb"]++
# TICS_LIST
tics_list["t"]++
tics_list["tics"]++
for(i in axis_list)for(k in tics_list)TICS_LIST[i k]++
# RANGE_LIST
range_list["r"]++
range_list["range"]++
for(i in axis_list)for(k in range_list)RANGE_LIST[i k]++
# LABEL_LIST
label_list["l"]++
label_list["label"]++
for(i in axis_list)for(k in label_list)LABEL_LIST[i k]++
# FORMAT_LIST
fromat_list["f"]++
fromat_list["format"]++
for(i in axis_list)for(k in fromat_list)FORMAT_LIST[i k]++
}
{
fname = "001"
font_size = 1
wafer_size = 150
def_scale = 10
ad("set nokey;")
ad("set ytics nomirror;")
for(i=1; i<=NF; i++){
if(next_flag && next_flag--)continue
if($i == "title" || $i == "t"){
ad("set title \"%s\"",$(i+1));
if(!gnuplot4_flag)ad(" noenhanced")
ad(";")
title_str = $(i+1)
next_flag++
continue
}
if($i == "file"){
fname = $(i+1)
fname_flag++
next_flag++
continue
}
if($i == "size" && number_judge($(i+1))){
graph_size *= $(i+1)
next_flag++
continue
}
if($i in TICS_LIST){
tics_set($i)
next_flag++
continue
}
if($i in RANGE_LIST){
range_set($i)
continue
}
if($i in LABEL_LIST){
label_set($i)
next_flag++
continue
}
if($i == "keypos" || $i == "kp"){
gsub("set nokey;", "", out);
trans_dir["r"] = trans_dir["right"] = "right"
trans_dir["l"] = trans_dir["left"] = "left"
trans_dir["t"] = trans_dir["top"] = "top"
trans_dir["b"] = trans_dir["bottom"] = "bottom"
i1 = $(i+1)
i2 = $(i+2)
if(i1 in trans_dir){
i1 = trans_dir[i1]
next_flag++
ad("set key %s", i1)
if(i2 in trans_dir){
i2 = trans_dir[i2]
ad(" %s", i2)
next_flag++
}
ad(";")
}else if(i1 == "off"){
ad("unset key;")
next_flag++
}
continue
}
if($i == "key" || $i == "k"){
gsub("set nokey;", "", out);
adop(" title \"%s\" ", $(i+1))
next_flag++
continue
}
if($i == "font"){
font_size = $(i+1)
if(terminal != "png" &&
term_font_set = font_size == 3 ? "font\",24\"" :
font_size == -3 ? "font\",8\"" : "" &&
++next_flag)continue
font_size_list["giant"] = font_size_list["g"] = font_size_list[2] = "giant"
font_size_list["large"] = font_size_list["l"] = font_size_list[1] = "large"
font_size_list["medium"] = font_size_list["m"] = font_size_list[0] = "medium"
font_size_list["small"] = font_size_list["s"] = font_size_list[-1] = "small"
font_size_list["tiny"] = font_size_list["t"] = font_size_list[-2] = "tiny"
font_size in font_size_list &&
(term_font_set = font_size_list[font_size]) &&
terminal != "png" &&
term_font_set = term_font_set == "giant" ? "font\",18\"" :
term_font_set == "large" ? "font\",17\"" :
term_font_set == "medium" ? "font\",14\"" :
term_font_set == "small" ? "font\",12\"" :
term_font_set == "tiny" ? "font\",10\"" : term_font_set;
}
if($i in FORMAT_LIST && format_set($i) && ++next_flag)continue
if($i == ","){
gsub("set nokey;", "", out);
N = split(w, T)
t_flag = w_flag = 0;
for(k=N; k>=1; k--){
if(T[k] == "title")t_flag++
if(T[k] == "w")w_flag++
if(T[k] == ",")break
}
keyn++
if(!t_flag)adop(" title \"%d\" ", keyn);
if(!w_flag)adop(" w lp pt 6 ")
adop(" , \"\" ");
continue
}
if($i == "axis" && adop(" axis x1y2 "))continue
if($i == "log" && $(i+1) in axis_list && ad("set logscale %s;", $(i+1)))continue
if($i == "u" && adop(" u %s ", $(i+1)) && ++next_flag)continue
if($i == "w"){
i1 = $(i+1)
if (i1 == "lp")adop(" w lp pt 6 ");
else if(i1 == "p") adop(" w p pt 5 ");
else if(i1 == "l") adop(" w l ");
continue
}
if($i == "pt"){
N = split(w, T)
flag = 0
for(k=N; k>1; k--){
if(T[k] == "pt" && natural_no_judge($(i+1)) && (T[k+1] = $(i+1)) && ++flag)break
if(T[k] == ",")break
}
if(flag){
w = ""
for(k=1; k<=N; k++)adop(sprintf(" %s",T[k]));
}
continue
}
if($i == "ps" || $i == "lt" || $i == "lw"){
N = split(w, T)
flag = 0
for(k=N; k>1; k--){
if((T[k] == "p" || T[k] == "lp" || T[k] == "l") && ++flag)break
if(T[k] == ",")break
}
if(flag)adop(" %s %d ", $i, natural_no_judge($(i+1)) ? $(i+1) : 1)
continue
}
# if gnuplot version > 5.0
if(($i == "hasen" || $i == "hasenn" || $i == "dot") && !gnuplot4_flag){
N = split(w,T);
flag = 0
for(k=N; k>1; k--){
if((T[k] == "lp" || T[k] == "l") && ++flag)break
if(T[k] == ",")break
}
if(!flag)adop(" w lp pt 6 ")
adop(" dt \"-\" ")
continue
}
if($i == "out" && ++out_flag)continue
if($i == "all"){
all_flag++
gsub("set nokey;", "", out);
k = i+1
while(k < NF){
if(!natural_no_judge($k))break
set_all_key_t[$k] = $(k+1)
k+=2
}
continue
}
if(all_flag){
if(($i == "vsplit" || $i == "vs") && !hsplit_flag && ++vsplit_flag)continue
if(($i == "hsplit" || $i == "hs") && !vsplit_flag && ++hsplit_flag)continue
}
# 複数列あってもいいかもしれないが一応allじゃないときに有効にする
if($i == "fit" && !all_flag && nf >= 2){
fit_flag++
# とりあえず20個くらいパラメータを初期化 ⇒ gauss以外はいらないかも?
for(k=1; k<=20; k++)ad("p%d=1;", k);
if($(i+1) == "gauss"){ # 一次元gauss
# 1:Height, 2:PeakPos, 3:Sigm, 4:Base ←収束しないこともあるのでこれらのparam_initは個別指定可能とする.初期値はある程度求めたあげた方が良いな…
for(k=1; k<=4; k++){
if(!number_judge($(i+k+1)))continue
ad("p%d=%s;", k, $(i+k+1))
next_flag++
}
ad("f(x) = p1 * exp(-((x - p2) / p3)**2) + p4;")
ad("fit f(x) \"%s\" via p1, p2, p3, p4;", filename)
fx = "ttt*exp(-((x - ttt) / ttt)^2) + ttt"
param_no = 4
next_flag++
}else if($(i+1) == "gauss2" && nf >= 3){ # 二次元gauss 表示は重ねるんじゃなくてsplitだな
# 1:Height, 2:PeakPos1, 3:Sigm1, 4:PeakPos2, 5:Sigm2, 6:Base
for(k=1; k<=6; k++){
if(!number_judge($(i+k+1)))continue
ad("p%d=%s;", k, $(i+k+1))
next_flag++
}
ad("f(x) = p1 * exp(-((x - p2) / p3)**2 - ((y - p4) / p5)**2) + p6;")
ad("fit f(x) \"%s\" via p1, p2, p3, p4, p5, p6;", filename)
fx = "ttt*exp(-((x - ttt) / ttt)^2 - ((y - ttt) / ttt)^2) + ttt"
param_no = 6
next_flag++
}else if($(i+1) == "poly" && natural_no_judge($(i+2))){ # 多項式一変数
param_no = $(i+2) + 1
st1 = "f(x) = "
st2 = "fit f(x) \"%s\" via "
for(k=1; k<=param_no; k++){
st1 = st1 sprintf("p%d*x**%d", k, param_no-k)
st2 = st2 sprintf("p%d", k)
fx = fx sprintf("tttx^%d", param_no-k)
if(k != param_no){
fx = fx " + "
st1 = st1 " + "
st2 = st2 ", "
}
}
st1 = st1 ";"
st2 = st2 ";"
ad(st1)
ad(st2, filename)
next_flag+=2
}else if($(i+1) == "poly2" && nf >= 3 && natural_no_judge($(i+2))){ # 多項式二変数 ⇒ これもアルゴ化したい
if($(i+2) == 2){ # 二次
ad("f(x) = p1*x**2 + p2*x*y + p3*y**2 + p4*x + p5*y + p6;")
ad("fit f(x) \"%s\" via p1, p2, p3, p4, p5, p6;", filename)
fx = "tttx^2 + tttxy + ttty^2 + tttx + ttty + ttt"
param_no = 6
next_flag+=2
}else{ # 一次(平面)
ad("f(x) = p1*x + p2*y + p3;")
ad("fit f(x) \"%s\" via p1, p2, p3;", filename)
fx = "tttx + ttty + ttt"
param_no = 3
next_flag++
}
}else{
# 引数何もない時は一次fit固定
ad("f(x) = p1*x + p2;")
ad("fit f(x) \"%s\" via p1, p2;", filename)
fx = "tttx + ttt"
param_no = 2
}
# fitting parameterをグラフ上に表示する. 4.0はsprintfが使えないので5.0以上限定
# 適当に4個ずつくらいで改行を入れてみる? ⇒ 改行文字が上手く入れられないからlabelを追加していくしかなさそう
if(!gnuplot4_flag && param_no){
st = "set label %d right at graph 0.95,0.05 sprintf(\"f(x) = %s\""
for(k=1; k<=param_no; k++){
st = st sprintf(", p%d", k)
}
st = st ");"
ad(st, ++label_cnt, fx)
gsub("ttt", "%g", out)
}
continue
}
# fit result text output
# ファイルの有無でfit.logを残すか残さないかshで判断する
if(fit_flag && ($i == "txt" || $i == "text" || $i == "dat"))print 1 > "fit_log_get"
if($i == "svg" && ++svg_flag)continue;
if(($i == "sixel" || $i == "term" || $i == "terminal") && ++sixel_flag)continue;
if($i == "map" && ++cmap_flag)continue;
if(cmap_flag){
if ($i == "gray") gray_color_flag++
else if($i == "viridis")viridis_color_flag++
}
if($i == "xline"){
maxminget()
printf"%s ",$(i+1) > xlinefile
for(k=1; k<=nf; k++)printf"%s ", maxt[k] > xlinefile
printf"\n%s ",$(i+1) > xlinefile
for(k=1; k<=nf; k++)printf"%s ", mint[k] > xlinefile
printf"\n\n" > xlinefile
next_flag++
xline_flag++
continue
}
if($i == "bubble" && ++bubble_flag)continue
if(bubble_flag){
if($i == "scale" && number_judge($(i+1)) && scale = $(i+1) && ++next_flag)continue;
if($i == "refoff" && ++refoff_flag)continue
}
if($i == "yline"){
maxminget()
printf"%s %s\n%s %s\n\n", nf==1?0:mint[1], $(i+1), nf==1?nr:maxt[1], $(i+1) > ylinefile
next_flag++
yline_flag++
continue
}
# inch
if($i == "wafer" && natural_no_judge($i+1)){
wafer_size = $(i+1)
if(!(wafer_size%2) && wafer_size<=12 && wafer_size>=2)wafer_flag++
if(!wafer_flag)continue
wafer_size *= 25.4 / 2
wafer_plot_point = 1000
pi = atan2(0, -0)
for(j=1; j<=wafer_plot_point; j++){
p = j * 2 * pi / wafer_plot_point;
print wafer_size*cos(p), wafer_size*sin(p), j/wafer_plot_point > waferfile
}
continue;
}
if($i == "bar" && nf > 1){
maxminget();
bar_flag++;
continue;
}
if(bar_flag){
if($i == "rot") rot_flag++;
if($i == "label")label_flag++;
}
if($i == "hedder"){
hedder_flag++
maxminget()
# 一行目はヘッダーとして読み込むので#でコメントアウト化
cmd = sprintf("sed -i -e \"1 s/^/#/g\" %s", filename);
system(cmd)
close(cmd)
for(k=1; k<=nf; k++)hedder_list[k] = data[1, k]
for(r=2; r<=nr; r++)for(k=1; k<=nf; k++)data[r-1, k] = data[r, k]
nr--
continue
}
}
for(i in format)adb("set format %s \"%%.%df\";", i, format[i])
# terminal type
adb("set grid;")
set_width = int(def_width * graph_size)
set_hight = int(def_height * graph_size)
if(out_flag){
# title & fname flag check
if(!fname_flag && title_str)fname = title_str
# exist file check
exst = fname ".png"
if(getline < exst > 0){
close(exst);
exst = sprintf("%s_t.png", fname)
if(fname~/^[0-9]+$/){
while(getline < (exst = sprintf("%03d.png", ++fname)) > 0)close(exst)
close(exst)
}
}
close(exst)
adb("set out \"%s\";", exst)
adb("set term png size %s, %s %s;", set_hight, set_width, term_font_set)
}else if(svg_flag){
adb("set term svg font \", %d\";", set_font)
}else if(sixel_flag){
adb("set term sixel size %s, %s font \", %d\";",set_hight, set_width, set_font)
}else{
adb("set out \"%s\";", displayfile)
adb("set term %s size %s, %s %s %s;", terminal, set_hight, set_width, term_font_set, gnuplot4_flag?"":"noenhanced")
}
if(w!~/ w /){
if(cmap_flag)adop(" w p pt 5 ps 1 ");
else adop(" w lp pt 6 ");
}else{
S = w;
nw = gsub(" w ", "", S);
S = w;
nc = gsub(" , ", "", S);
if(nw < nc + 1)adop(" w lp pt 6 ")
}
if(w~/axis/){
ad("set y2tics;")
}
if(w~/,/){
N = split(w, T)
flag = 0;
for(k=N; k>=1; k--){
if(T[k] == "title" && ++flag)break
if(T[k] == ",")break
}
if(!flag)adop(" title \"%d\" ", ++keyn);
}
# graph type select
if(cmap_flag){
ad("set palette defined ")
if (gray_color_flag) ad("( 0 \"#000000\", 1 \"#252525\", 2 \"#525252\", 3 \"#737373\", 4 \"#969696\", 5 \"#BDBDBD\", 6 \"#D9D9D9\", 7 \"#F0F0F0\", 8 \"#FFFFFF\");")
else if(viridis_color_flag)ad("( 0 \"#440154\", 1 \"#472c7a\", 2 \"#3b518b\", 3 \"#2c718e\", 4 \"#21908d\", 5 \"#27ad81\", 6 \"#5cc863\", 7 \"#aadc32\", 8 \"#fde725\");")
else ad("( 0 \"#000090\", 1 \"#000fff\", 2 \"#0090ff\", 3 \"#0fffee\", 4 \"#90ff70\", 5 \"#ffee00\", 6 \"#ff7000\", 7 \"#ee0000\", 8 \"#7f0000\");")
ad("set view map;")
if(wafer_flag){
wafer_setting()
# どうせカラーはnmであることが多いのでdefaultはそうする
if(out!~/cblabel/)ad("set cblabel [nm];")
}
ad("splot \"%s\" u 1:2:3 %s palette", filename, w)
if(wafer_flag)ad(", \"%s\" w l lt -1 lw 2;", waferfile)
ad(";")
}else if(bubble_flag){
# ここでdefaultのスケールを設定
if(scale == "")scale = def_scale
tmp_scale = scale
scalestr = scale
scale = 15 / scale
ad("set multiplot;")
# ver4.0はcirclesに対応していないので、psで対応するため、レンジを固定する
if(wafer_flag || gnuplot4_flag){
wafer_setting()
ad("ref_pos=%s;", wafer_size*0.93)
if(!refoff_flag && !gnuplot4_flag){
ad("ref_scale=%s;", 15)
ad("scalestr=\"%s\";", scalestr)
ad("plot \"%s\" u (1>0?ref_pos:0):(1>0?ref_pos:0):(1>0?ref_scale:0) every 1 w circles lc \"gray\" fs solid border -1, \"\" u (1>0?ref_pos:0):(1>0?ref_pos:0):(1>0?scalestr:0) every 1 w labels offset 0,0;", filename)
}
ad("set parametric;")
ad("plot [0:2*pi] wafer_size*cos(t),wafer_size*sin(t) w l lt -1 lw 2;")
}else{
# 横縦軸のレンジを固定する
maxminget();
ad("set xrange [%s:%s];", mint[1]-(maxt[1]-mint[1])/10, maxt[1]+(maxt[1]-mint[1])/10);
ad("set yrange [%s:%s];", mint[2]-(maxt[2]-mint[2])/10, maxt[2]+(maxt[2]-mint[2])/10);
}
# gnuplot ver4 correspondesce
# 別にこっちに統一してもいいけど5.0verも残しておく
if(gnuplot4_flag){
maxminget();
# gnuplotバージョンによって〇のポイントタイプが異なる。6が中抜き円、Ver4.0は7が中抜き円
circle_type = 7
scale /= 4
# refの表示
ad("set label %d \"%s\" center at first ref_pos,ref_pos;", ++label_cnt, scalestr)
scale_plot = scale * tmp_scale
ad("b=%s;", scale_plot<0 ? -scale_plot : scale_plot);
ad("plot \"%s\" u (1>0?ref_pos:0):(1>0?ref_pos:0) every ::1::1 w lp pt %d ps b*2 lt %d lw 2 notitle;", filename, circle_type, scale_plot<0?1:2)
for(i=1; i<=nr; i++){
ad("set label %d \"%s\" center at first %s,%s;", ++label_cnt, data[i,3], data[i,1], data[i,2])
scale_plot = data[i,3] * scale
ad("i=%d;", i-1);
ad("b=%s;", scale_plot<0 ? -scale_plot : scale_plot);
ad("plot \"%s\" u 1:2 every ::i::i w lp pt %d ps b*2 lt %d lw 2 notitle;", filename, circle_type, scale_plot<0?1:2) # ここで正負の色決めてます
}
}else{
ad("plot \"%s\" u 1:2:($3<0?-$3*%f:0) w circles lc 4 fs solid border -1, \"\" u 1:2:3 w labels offset 0,0;", filename, scale)
ad("plot \"%s\" u 1:2:($3>0?$3*%f:0) w circles lc \"light-blue\" fs solid border -1, \"\" u 1:2:3 w labels offset 0,0;", filename, scale)
}
ad("unset multiplot;")
}else if(bar_flag){
# ver4.0はxlabelに行数しか指定できない(xtic()が使えない) set xformat ""してから個別にラベルを配置するか…
# なので横軸が1列目のデータではなく行数になる…⇒ 1列目を文字列変換すればなんとかなるか?
ad("set style fill solid border;")
ad("set boxwidth 0.925;")
if(out!~/yrange/){
maxall = maxt[2]
if(all_flag)for(k=2; k<=nf; k++)if(maxt[k] > maxall)maxall = maxt[k]
ad("set yrange [:%s];", maxall*1.1)
}
if(rot_flag)ad("set xtics rotate by -90;")
if(all_flag){
if(label_flag && gnuplot4_flag){
maxminget();
axis_cnt = 0
for(i=1; i<=nr; i++){
for(k=2; k<=nf; k++){
ad("set label %d \"%s\" center at first %s,%s;", ++label_cnt, data[i,k], axis_cnt++, data[i,k]+maxall*0.02)
}
axis_cnt++
}
}
ad("plot \"%s\" u ($0*%d):2", filename, nf)
if(nf == 3 && !gnuplot4_flag)ad(":xtic(1)")
ad(" t")
ad(" \"%s\"", set_all_key_t[1]?set_all_key_t[1]:1)
ad(" w boxes lw 1 lt 3")
if(label_flag && !gnuplot4_flag)ad(", \"\" u ($0*%d):2:2 t \"\" w labels offset 0, 1", nf)
for(i=2; i<nf; i++){
ad(", \"\" u ($0*%d+%d):%d", nf, i-1, i+1)
if(i == int(nf/2) && !gnuplot4_flag)ad(":xtic(1)")
ad(" t")
ad(" \"%s\"", set_all_key_t[i]?set_all_key_t[i]:i)
ad(" w boxes lw 1 lt %d", i+3)
if(label_flag && !gnuplot4_flag)ad(", \"\" u ($0*%d+%d):%d:%d t \"\" w labels offset 0, 1", nf, i-1, i+1, i+1)
}
}else{
if(label_flag && gnuplot4_flag){
maxminget();
for(i=1; i<=nr; i++)ad("set label %d \"%s\" center at first %s,%s;", ++label_cnt, data[i,2], i-1, data[i,2]+maxt[2]*0.02)
}
ad("plot \"%s\" u 0:2", filename)
if(!gnuplot4_flag)ad(":xtic(1)")
ad(" w boxes lw 1 lt 3")
if(label_flag && !gnuplot4_flag)ad(", \"\" u 0:2:2 w labels offset 0, 1")
}
if(yline_flag)ad(", \"%s\" u ($1-1):2 t \"\" w l lt -1 lw 3", ylinefile)
ad(";")
}else if(all_flag){
if(vsplit_flag){
# ad("set multiplot layout %d,1;", nf-1) # ver4.0ではlayoutは存在しない ⇒ 存在する場合はそのまま使えば?
ad("set multiplot;")
ad("set format x \"\";")
# ver4.0ではscreenは使えないのでベタ書きで設定する。
# ad("set lmargin screen 0.1;")
ad("set lmargin 10;") # 左だけ軸の数字がちゃんと入るようにこれくらい空ける
# ad("set rmargin screen 0.9;") # y2軸使用しない場合は設定不要なはず
graph_no = nf - 1
ratio_set = (gnuplot4_flag?1.1:1.15) / graph_size # 係数は経験則
all_size = 30
for(i=1; i<nf; i++){
# ad("set tmargin screen %s;", 0.95-0.90/(nf-1)*(i-1))
# ad("set bmargin screen %s;", 0.95-0.90/(nf-1)*i+0.025)
ad("set tmargin %s;", (2.5 + all_size / graph_no * (i-1)) / ratio_set) # 係数は経験則
ad("set bmargin %s;", (3 + all_size - all_size / graph_no * i) / ratio_set)
if(i == nf - 1){
ad("set format x \"ttt\";")
gsub("ttt", "%g", out);
}
ad("plot \"%s\" u 1:%d t \"%s\" %s", filename, i+1, hedder_list[i+1]?hedder_list[i+1]:set_all_key_t[i]?set_all_key_t[i]:i, w)
if(xline_flag)ad(", \"%s\" u 1:%d t \"\" w l lt -1 lw 3", xlinefile, i+2)
ad(";")
}
}else if(hsplit_flag){
ad("set multiplot;")
graph_no = nf - 1
ratio_set = (gnuplot4_flag?1.1:1) / graph_size
all_size = 77
for(i=1; i<nf; i++){
# if(i>1)ad("set format y \"\";")
ad("set lmargin %s;", (5 + all_size / graph_no * (i-1)) / ratio_set)
ad("set rmargin %s;", (5 + all_size - all_size / graph_no * i) / ratio_set)
ad("plot \"%s\" u 1:%d t \"%s\" %s", filename, i+1, hedder_list[i+1]?hedder_list[i+1]:set_all_key_t[i]?set_all_key_t[i]:i, w)
if(yline_flag)ad(", \"%s\" u ($1-1):2 t \"\" w l lt -1 lw 3", ylinefile)
ad(";")
}
}else{
ad("plot \"%s\" u 1:2 t", filename)
ad(" \"%s\"", hedder_list[1]?hedder_list[1]:set_all_key_t[1]?set_all_key_t[1]:1)
ad(" %s", w)
if(xline_flag)ad(", \"%s\" u 1:3 t \"\" w l lt -1 lw 3", xlinefile)
for(i=2; i<nf; i++){
ad(", \"%s\" u 1:%d t", filename, i+1)
ad(" \"%s\"", hedder_list[i]?hedder_list[i]:set_all_key_t[i]?set_all_key_t[i]:i)
ad(" %s", w)
if(xline_flag)ad(", \"%s\" u 1:%d t \"\" w l lt -1 lw 3", xlinefile, i+2)
if(yline_flag)ad(", \"%s\" t \"\" w l lt -1 lw 3", ylinefile)
}
ad(";")
}
}else{
if(wafer_flag){
wafer_setting()
ad("set parametric;")
ad("set multiplot;")
ad("plot [0:2*pi] wafer_size*cos(t),wafer_size*sin(t) w l lt -1 lw 2;")
}
ad("plot \"%s\" %s", filename, w)
if(fit_flag)ad(", f(x) w l")
if(xline_flag){
flag = 0
for(i=1; i<=nf; i++){
if(!index(out, sprintf(":%d", i)))continue
ad(", \"%s\" u 1:%d t \"\" w l lt -1 lw 3", xlinefile, i+1)
flag++
}
if(!flag){
ad(", \"%s\"", xlinefile)
if(nf != 1)ad(" u 1:3")
ad(" t \"\" w l lt -1 lw 3")
}
}
if(yline_flag)ad(", \"%s\" t \"\" w l lt -1 lw 3", ylinefile)
ad(";")
}
}
END{
print out > optfile;
}' optfile=$optionfile filename=$filename nf=$nf waferfile=$waferfile\
terminal=$terminal displayfile=$displayfile xlinefile=$xlinefile\
ylinefile=$ylinefile term_font_set=$term_font_set gnuplot4_flag=$gnuplot4_flag\
graph_size=$graph_size def_height=$def_height def_width=$def_width
$gnuplotcmd <<EOF
load '$optionfile'
EOF
if [ $gnuplot4_flag -eq 0 ] && [ `echo $@ grep out | wc -l` -gt 0 ] && [ `whereis mogrify | awk 'NF>1' | wc -l` -gt 0 ]; then
# mogrify -fuzz 10% -trim +repage $out_file
mogrify -trim +repage $out_file
fi
fi
# png出力する場合にimagemagickで表示するようにする
if [ -f $displayfile ]; then
if [ $terminal = "png" ] && [ `whereis display | awk 'NF>1' | wc -l` -gt 0 ]; then
display $displayfile
fi
rm $displayfile
fi
# temp file delete
if [ -f $filename ]; then rm $filename; fi
if [ -f $optionfile ]; then rm $optionfile; fi
if [ -f $waferfile ]; then rm $waferfile; fi
if [ -f $xlinefile ]; then rm $xlinefile; fi
if [ -f $ylinefile ]; then rm $ylinefile; fi
if [ -f fit_log_get ]; then
rm fit_log_get
elif [ -f fit.log ]; then
rm fit.log
fi
おわりに
gnuplotとawkしかないような環境でログデータ分析を行う場合に、これひとつつっこんでおけば分析が捗るような気がします。