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'; } }