GNUPLOT

- not so Frequently Asked Questions -

update 2004/8/31

gnuplot 入門 --- 生活編

It's working !
(Anakin, Tatooine)

作業のバッチ化

ここでは,数値計算編の最後に保存したプロットファイル "output.plt" を使って,「その後」の仕事を楽に する方法を概説します.このファイルを覗いてみると,作業中に設定した部分 (軸の範囲やプロットするファイル名)と,その他のデフォルトで設定されてい る部分が混在しているのが分かると思います.ちょっと見づらいので,デフォ ルトで設定されている部分を消して,自分で設定したものだけを残してみましょ う.但し,termianlとplotの部分は長くなりすぎるので,継続行記号(backslash)を 使って折り返しています.

#!/usr/local/bin/gnuplot -persist
# set terminal postscript landscape noenhanced monochrome \
#              dashed defaultplex "Helvetica" 14
# set output 'output.ps'
set xlabel "x" 0.000000,0.000000  ""
set ylabel "y=exp(-x)" 0.000000,0.000000  ""
set title "Pade approximation" 0.000000,0.000000  ""
set xrange [ 0 : 2 ] noreverse nowriteback
set yrange [ 0 : 1 ] noreverse nowriteback
set mxtics 5.000000
set mytics 5.000000
set xtics border mirror norotate 1
set ytics border mirror norotate 0.5
plot "output.dat" using 1:2 title "Analytical" w l, \
"output.dat" using 1:3 title "L=1, M=2" w l, \
"output.dat" using 1:4 title "L=2, M=1" w l
#    EOF

PostScriptに出力する部分はコメントアウトされています.gnuplotを再び 起動し,このファイルをloadコマンドで読み込めば,同じグラフを もう一度描くことができます.また,新しい計算結果等を同じファイル(ここ ではoutput.dat)に書き込むようにすれば,計算結果を決まったフォーマットで すぐに見ることができて便利です.

gnuplot> load "output.plt"

他に,gnuplot起動時にこのファイル名をオプションとして渡す方法があり ますが,そのままではグラフを表示した直後にgnuplotが終了してしまい,画 面がすぐに消えてしまいます.表示した画面を残すには,上のプロットファイ ルの最後(plotコマンドの後)に pause -1 を入れておきます.こう すると,リターンキーが押されるまで画面表示が止まります.

% gnuplot output.plt

gnuplotの画面表示を残すもう一つの方法として,起動時のオプションに -persistをつける方法があります.gnuplotそのものは終了しますが, 画面の表示は残ったままになります.

% gnuplot -persist output.plt

上のプロットファイルの例を見ると,一行目にこのオプションが書かれて のがわかります.gnuplotが書き出すプロットファイルは,実行可能の許可を 与えてやれば,スクリプトとしてそのまま実行することができます.

% chmod +x  output.plt
% ./output.plt

なお,この方法では,画面を閉じるためにkillコマンドやウィンドウのク ローズボタン等を使ってプロセスそのものを殺す必要がありますので,何度も プロットを繰り返す場合は pause -1を使う方法が便利でしょう.

プロットファイルをloadし直して,再び対話的にプロット作業を進める事も できますが,ファイルが出来た後ではバッチ処理による作業の方が効率的です. まずファイルの最後に pause -1 を入れておいて,

  • プロットファイルをEditorを使って修正する
  • プロット結果を画面で見る

という作業を繰り返して,満足のいくグラフを作っていきます. また,最終目的がPostScriptであれば,

  • プロットファイルを修正する
  • PostScriptに出力する
  • PostScriptファイルをgv等でプレビューする

という作業の繰り返しになります.この場合は,上ではコメントアウトされ ていた set terminal postscript と出力ファイル名をプロット ファイルに書いておきます.また,画面には描かれないので, pauseを入れる必要はありません.

up

図の大量生産

研究活動にgnuplotが特に便利なのは,出来上がったプロットファイルを 再利用できる点です.研究を続けていると,枠や軸名が全く同じで中の数値だ けが異なっているような図を何度も描かなければならないことがあります. gnuplotなら,一つのプロットファイルを使い,その中の表示するファイル名 の部分だけを変更することで,次々と別の図を作成することができますので効 率的です.これには,plot "datafile"の datafileの部分だけを書 き直しても良いし,あるいはdatafileの中身そのものを新しいデータに上書き して何度もプロットを繰り返すこともできます.

gnuplotのバッチモードは大量のデータを処理するときに非常に便利です. グラフを作りたいデータの数が多いとき,市販のグラフソフトを使いながら一 枚一枚図を作っていては,いつまで経っても仕事が終わりません(簡単にでき るソフトもあるかもしれません.このページの作者が知らないだけです). gnuplotとUNIXのコマンドを組み合わせて,全てのデータを一気にグラフにす る方法を考ます.

あるディレクトリの中に,calc1.dat, calc2.dat, calc3.dat のように番 号が付いたデータファイルがたくさん入っているとします.各々のデータファ イルの中身は,(X,Y)の組だけが書かれた単純な数値データです.まず, calc1.dat だけをとりだして,この図を作成するプロットファ イルを書きます.ここでは,数値計算編で行っ たように,図の表題,軸名,XYの範囲,目盛間隔だけを指定します.

set terminal png
set output "calc1.png"
set xlabel "Energy [MeV]"
set ylabel "Cross Section [b]"
set title "(n,2n) reaction"
set xrange [ 0 : 20 ]
set yrange [ 0 : 2 ]
set mxtics 5
set mytics 5
set xtics 5
set ytics 0.5
plot "calc1.dat" using 1:2 notitle w l

このファイル data.plt をgnuplotに「食わす」 とPNGの画像が同じディレクトリに出来上がります.EPSのファイルを作りたけ れば, set terminal でPostscriptを指定し,あとファイル名を calc1.eps等に変更します.

% gnuplot < data.plt
calc1.png

このプロットファイルを他のデータに流用する方法を考えます.上で作った data.pltで,書き直さないといけないのは,"calc1.dat"と"calc1.png"の2 つのファイル名だけです.残念ながらgnuplotは文字列定数を扱えないので, これらを変数にはできません.ここではsedを使ってcalc1 をcalc2に置換する方法と,ファイル名をshellス クリプトの引数として外部から与える方法を紹介します.


sedを使ってファイルの一部を置換するには,次のようにします.

% sed "s/calc1/calc2/g" data.plt | gnuplot

たったこれだけで,新しい図calc2.pngが出来上がります.あとはこの作 業を全データファイルに対して行うだけです.データファイルの数があまり多 くないなら,コマンドラインだけで作業できます.

csh, tcsh

% foreach i (calc2 calc3 calc4 cal5)
foreach? sed "s/calc1/$i/g" data.plt | gnuplot
foreach? end

sh, bash

$ for i in calc2 calc3 calc4 cal5 ; do
> sed "s/calc1/$i/g" data.plt | gnuplot
> done

データファイル数が多い時は,以下のようにsedを使って,datという拡張 子が付いたファイル名から拡張子以外の部分だけを取り出して処理します. クォートとバッククォートを間違えないように.内側のsedは変数$iに ある".dat"を消す部分,外側はその文字列で calc1 を置換するためのもので す.

$ for i in *.dat ; do
> sed "s/calc1/`echo $i | sed "s/\.dat$//"`/g" data.plt | gnuplot
> done

図を一枚ずつ描くshellスクリプトを書くこともできます.こちらの方が, 後で再利用できるので便利かもしれません.スクリプトには,上にあるような sedで変換しながらgnuplotに流し込む行を,ファイルの数だけ並べれば良いの ですが,

#!/bin/sh
sed "s/calc1/calc2/g" data.plt | gnuplot
sed "s/calc1/calc3/g" data.plt | gnuplot
sed "s/calc1/calc4/g" data.plt | gnuplot
sed "s/calc1/calc5/g" data.plt | gnuplot
...

以下のように awkを使って lsコマンドの出力を整形すれば,このスクリ プトを簡単に作成することができます.スクリプトのファイルを作るには,下 のコマンドの実行結果をファイルにリダイレクトします(コマンド > script.sh).

% ls *.dat | awk '{printf("sed \"s/calc1/%s/g\" data.plt | gnuplot\n",$1)}'



プロットファイルの文字列を置き換える別の方法と して,shellスクリプトの中に直接gnuplotのコマンドを書いてしまい,その中 のファイル名をshellの変数にする方法もあります.gnuplotのコマンドをshell スクリプトに書き込むには,以下のようなHere Documentを使います.今度はデー タファイルcalc1.datから,EPSファイル calc1.epsを作ってみましょう.

#!/bin/sh
gnuplot << EOF
set terminal postscript eps color enhanced
set output "$1.eps"
set xlabel "Energy [MeV]"
set ylabel "Cross Section [b]"
set title "(n,2n) reaction"
set xrange [ 0 : 20 ]
set yrange [ 0 : 2 ]
set mxtics 5
set mytics 5
set xtics 5
set ytics 0.5
plot "$1.dat" using 1:2 notitle w l
EOF

見て分かるように,データファイルと出力EPSファイル名の拡張子を除いた 部分が,変数$1 に置き換えられています.この変数はスクリプト plot.shのコマンドライン引数として与えられます ので,下のようにコマンドラインから実行すれば,calc1.datから calc1.eps という図ができあがります.この方法なら,任意のディレクト リにあるデータをプロットし,その結果を同じディレクトリのファイルと して生成することができます.

$ ./plot.sh calc1

データファイルとEPSファイルの名前を変える場合は,上のスクリプトの中 にあるどちらかの$1$2としておき,コマンドラインで2つ の引数を与えます.

さらに次のようなshellスクリプトやforeachなどを用いれば,上の例と同様 な図の大量生産が可能になります.

#!/bin/sh
./plot.sh  calc1
./plot.sh  calc2
./plot.sh  calc3
./plot.sh  calc4
...
from Dr. Sato. Thanks !
manyfigure.png
up