pregnuplot を作ってみた(3)
プログラムファイルの続きを示します。プログラムファイルの続き
このプログラムファイルにバグがありましたので、修正しました。(2013/3/7 17:38)
#------ gnuplotファイルの出力 ------
$gpfile = $pgpfile;
$gpfile =~ s/.pgp$/.gnu/;
open(OUT, '> '.$gpfile);
print (OUT "#% !TEX TS-program = gnuplot\n"); #gnuplotが%のコメントをサポートしていないため、
print (OUT "#% !TEX encoding = UTF-8 Unicode\n"); #事実上意味ない出力になっている。
print (OUT "#\n");
print (OUT "#グラフ(Pregnuplotにより作成)\n");
print (OUT "#\n");
print (OUT "\n");
print (OUT "#グラフの範囲を設定\n");
foreach $i ('XMIN', 'XMAX', 'YMIN', 'YMAX') {
if ($pgpdata{$i} eq "") {
print "$iは必須項目なので入力し直してください\n";
close OUT;
exit 1;
}else {
print (OUT "$i = $pgpdata{$i}\n");
}
}
print (OUT "\n");
print (OUT "#座標系(coordinate system)の幅と高さ\n");
print (OUT "CWIDTH = XMAX-XMIN\n");
print (OUT "CHEIGHT = YMAX-YMIN\n");
$CWIDTH = $pgpdata{'XMAX'} - $pgpdata{'XMIN'};
$CHEIGHT = $pgpdata{'YMAX'} - $pgpdata{'YMIN'};
print (OUT "\n");
print (OUT "#軸に書き込む文字の軸からの距離\n");
print (OUT "XDCA = 0.05*CWIDTH\n");
print (OUT "YDCA = 0.05*CHEIGHT\n");
print (OUT "\n");
print (OUT "#出力先\n");
print (OUT "set terminal $pgpdata{'TERMINAL'}\n");
if ($pgpdata{'OUTFILE'} ne ""){
print (OUT "set output \"$pgpdata{'OUTFILE'}\"\n");
}
print (OUT "\n");
print (OUT "#デフォルトの外側に書かれる座標軸は表示しない\n");
print (OUT "unset border\n");
print (OUT "unset tics\n");
print (OUT "\n");
print (OUT "#矢印の座標軸\n");
print (OUT "set arrow 1 from $pgpdata{'XMIN'},0 to $pgpdata{'XMAX'},0 linestyle -1\n");
print (OUT "set arrow 2 from 0,$pgpdata{'YMIN'} to 0,$pgpdata{'YMAX'} linestyle -1\n");
print (OUT 'set label 1 "$x$" at XMAX-XDCA, -YDCA'."\n");
print (OUT 'set label 2 "$y$" at -XDCA, YMAX-2*YDCA'."\n");
#原点
@temp012 = split(",",&ENWS($pgpdata{'LABELO'}));
print (OUT "set label 3 \"O\" at ($temp012[0])*XDCA, ($temp012[1])*YDCA\n");
#x=a型直線
print (OUT "#x=a型の直線\n");
foreach $i ('XEA0', 'XEA1', 'XEA2', 'XEA3', 'XEA4', 'XEA5', 'XEA6', 'XEA7', 'XEA8', 'XEA9'){
if ($pgpdata{$i} ne ""){
print (OUT "set arrow from $pgpdata{$i},YMIN to $pgpdata{$i},YMAX nohead lw 2 lt -1\n");
}
}
#その他の点のラベル
print (OUT "#点の座標を表すラベル\n");
# 名前、その点のx座標、その点のy座標、ずらす方向、倍率
foreach $i ('LB0', 'LB1', 'LB2', 'LB3', 'LB4', 'LB5', 'LB6', 'LB7', 'LB8', 'LB9') {
next if ($pgpdata{$i} eq "");
@tempL = split(",",$pgpdata{$i});
@temp012 = split(",",&ENWS($tempL[3]));
print (OUT "set label \"$tempL[0]\" at $tempL[1]+$tempL[4]*($temp012[0])*XDCA, $tempL[2]+$tempL[4]*($temp012[1])*YDCA\n");
}
#点の位置を示す点線
print (OUT "#点の位置を示す座標軸までの点線\n");
# その点のx座標、その点のy座標、点線の行き先(x軸、y軸、両方)
foreach $i ('PL0', 'PL1', 'PL2', 'PL3', 'PL4', 'PL5', 'PL6', 'PL7', 'PL8', 'PL9') {
next if ($pgpdata{$i} eq "");
@tempP = split(",",$pgpdata{$i});
if ($tempP[2] eq "x" || $tempP[2] eq "xy") {
print (OUT "set arrow from $tempP[0],$tempP[1] to $tempP[0],0 nohead lt 0 lw 3\n");
}
if ($tempP[2] eq "y" || $tempP[2] eq "xy") {
print (OUT "set arrow from $tempP[0],$tempP[1] to 0,$tempP[1] nohead lt 0 lw 3\n");
}
}
#縦横比
print (OUT "\n");
print (OUT "#縦横比(縦/横)\n");
if ($pgpdata{'RATIO'} ne "") {
print (OUT "set size ratio $pgpdata{'RATIO'}\n");
}
print (OUT "\n");
#曲線のプロット
print (OUT "#プロット\n");
print (OUT "plot [XMIN:XMAX] [YMIN:YMAX] \\\n");
foreach $i ('FX0', 'FX1', 'FX2', 'FX3') {
if($pgpdata{$i} ne ""){
print (OUT "$pgpdata{$i} lw 2 lt -1 notitle, \\\n");
}
}
#
#領域描画
#
#除数(divisor)
# 一応30位が適当かと...
# 多くすると斜線の間隔が狭くなる。
$DIV = 30;
#加数(addend)
$ADD = $CHEIGHT / $DIV;
#傾き(inclination)
$INC = $CHEIGHT / $CWIDTH;
if ($pgpdata{'DOMAIN'} ne ""){
for ($i = $pgpdata{'YMIN'}-$CHEIGHT+$ADD ; $i < $pgpdata{'YMAX'}; $i+=$ADD) {
$DOMAIN0 = $pgpdata{'DOMAIN'};
$DOMAIN0 =~ s/y/(($INC)*(x-XMIN)+($i))/g;
print (OUT "$DOMAIN0 ? ($INC)*(x-XMIN)+($i) : 1/0 notitle lw 1 lt -1,\\\n");
}
}
#ダミーのプロット(この前がコンマで終わっているための調整)
print (OUT "1/0 notitle \n");
print (OUT "\n");
close(OUT);
$ecode = system("gnuplot ".$gpfile);
if ($ecode != 0) {
print "system(gnuplot) returned error code $ecode.\n";
exit $ecode;
}
exit 0;
#------ ENSW情報から、(x,y)=(0,0)~(-1,-2)を出力 ------
sub ENWS {
if ($_[0] eq "E") { return '1,0'; }
elsif ($_[0] eq "N") { return '0,1'; }
elsif ($_[0] eq "W") { return '-1,0'; }
elsif ($_[0] eq "S") { return '0,-1'; }
elsif ($_[0] eq "NE") { return '1,1'; }
elsif ($_[0] eq "NW") { return '-1,1'; }
elsif ($_[0] eq "SW") { return '-1,-1'; }
elsif ($_[0] eq "SE") { return '1,-1'; }
elsif ($_[0] eq "NEE") { return '2,1'; }
elsif ($_[0] eq "NNE") { return '1,2'; }
elsif ($_[0] eq "NNW") { return '-1,2'; }
elsif ($_[0] eq "NWW") { return '-2,1'; }
elsif ($_[0] eq "SWW") { return '-2,-1'; }
elsif ($_[0] eq "SSW") { return '-1,-2'; }
elsif ($_[0] eq "SSE") { return '1,-2'; }
elsif ($_[0] eq "SEE") { return '2,-1'; }
}