GNUPLOT

- not so Frequently Asked Questions -

update 2005/11/19

データファイルの数値のプロット (その2)

1 | 2 | 3 | 4

一つのファイルに入った複数のデータをプロットするには?

一つのファイルに複数のデータを書いてそれらを同時にプロットするには, usingとindexを使います.

X座標が同じでY座標が異なるデータをプロットするときは,データを表形 式で表して,usingでプロットするデータを指定するのが簡単です.

#   X         Y1         Y2         Y3
   -1.0000    0.0000     0.0000     1.0000
   -0.9000    0.5700     1.1769     0.7150
   -0.8000    1.0800     1.4400     0.4600
   -0.7000    1.5300     1.4997     0.2350
   -0.6000    1.9200     1.4400     0.0400
   -0.5000    2.2500     1.2990    -0.1250
   -0.4000    2.5200     1.0998    -0.2600
   -0.3000    2.7300     0.8585    -0.3650
   -0.2000    2.8800     0.5879    -0.4400
   -0.1000    2.9700     0.2985    -0.4850
    0.0000    3.0000    -0.0000    -0.5000
    0.1000    2.9700    -0.2985    -0.4850
    0.2000    2.8800    -0.5879    -0.4400
    0.3000    2.7300    -0.8585    -0.3650
    0.4000    2.5200    -1.0998    -0.2600
    0.5000    2.2500    -1.2990    -0.1250
    0.6000    1.9200    -1.4400     0.0400
    0.7000    1.5300    -1.4997     0.2350
    0.8000    1.0800    -1.4400     0.4600
    0.9000    0.5700    -1.1769     0.7150
    1.0000    0.0000    -0.0000     1.0000
gnuplot> plot "test.dat" using 1:2 with lines,\
              "test.dat" using 1:3 with lines,\
              "test.dat" using 1:4 with lines
fig/sample7.2a

X座標が異なる場合は,複数のデータを2行の空行で区切ってブロックにす る方法を使います.(注:ここでいうブロックとは,gnuplotのマニュアルにあ るdatablockとは異なり,通常の意味でのデータのかたまりを指します. gnuplotでは1行の空行で区切られたデータのかたまりをblockと定義してます)

#  X     Y     Yerror
   1.0   1.2   0.1
   2.0   1.8   0.1
   3.0   1.6   0.1


   1.1   0.8   0.2
   2.1   0.3   0.2
   3.1   1.0   0.2


   1.2   1.5   0.3
   2.2   2.3   0.3
   3.2   3.1   0.3
gnuplot> plot "test.dat" using 1:2 with lines
fig/sample7.2b
gnuplot> plot "test.dat" using 1:2:3 with yerrorbars
fig/sample7.2c

ここの例で分かるように,データをブロックにしてプロットした場合, 全部が同じ線種・記号で表示されます.各ブロックに対して異なる線種・ 記号を与えるには,それぞれのブロックのindexを使います. 初めのブロックのindexは0,次のブロックは1,という順序で,indexが 与えられており,これを指定してプロットします.

gnuplot> plot "test.dat" index 0 using 1:2:3 with yerrorbars,\
              "test.dat" index 1 using 1:2:3 with yerrorbars,\
              "test.dat" index 2 using 1:2:3 with yerrorbars
fig/sample7.2d

indexは範囲を指定することもできます.上の例で,index 0とindex 1に 同じ記号を使い,2だけを変えるには,次のようにします.

gnuplot> plot "test.dat" index 0:1 using 1:2:3 with yerrorbars,\
              "test.dat" index 2   using 1:2:3 with yerrorbars
fig/sample7.2e

ファイルの数値をプロットする時に,数値を修正したい.

usingの後に指定するカラムに簡単な演算ができます.プロットする データとして次のものを用い,Y座標をそのまま,Y座標の値を2倍したもの, 平方根をとったもの,対数をとったもの,を同時にプロットしてみます.

#  X     Y
   1.0   1.2
   2.0   1.8
   3.0   1.6
gnuplot> plot "test.dat" using 1:2          with points,\
              "test.dat" using 1:($2*2)     with points,\
              "test.dat" using 1:(sqrt($2)) with points,\
              "test.dat" using 1:(log($2))  with points
fig/sample7.3

$nで,nカラムのデータを指定し,それに演算を施します.このとき計算 式は必ず()で括ります. using 1:sqrt($2) の様な書き方はエラーに なります.同じ方法を使って複数のカラムの演算結果をプロットすることもで きます.例えば2カラムと3カラムの積をプロットするには, using 1:2:($2*$3)とします.


この方法は誤差付きデータを表示するときに便利なことがあります. gnuplotでは,誤差を絶対値で与えますが,データファイルにはパーセント のような相対値で表示されていることが少なくありません.using 1:2:($2*$3/100.0)とすれば,ファイルの中身を書き直すことなく%表示 のデータをプロットすることができます.

データファイルにプロットのコマンドも一緒に入れたい.

gnuplotではプロットするデータのファイルと,実行するコマンドを記述し たファイルは独立ですが,単純なデータなら一つのファイルに入れてしまうこ とができます.基本的には,コマンドが記述されたファイルを作ってバッチ処 理する方法ですが,このファイルのplotコマンド部分に,プロットするファイ ル名として "-" を指定し,その後に数値データを書きます.データの終りは "e" で始まる行です.

set xrange [0:5]
set yrange [0:3]
plot "-" using 1:2:3 w yerrorbars
#  X     Y     Z 
   1.0   1.2   0.2
   2.0   1.8   0.3
   3.0   1.6   0.2
   4.0   1.2   0.2
end
pause -1

このようなデータ込みのgnuplot制御用ファイルを用意し,gnuplot の起動時にコマンドラインオプションでファイル名を与えます.

 % gnuplot "test.plt"

但し,この方法ではreplotコマンドは使えません.gnuplotはデータを記 憶しないので,replotとすると,再び標準入力からデータを読み込もうとしま す.

特定のデータをスキップしてプロットしたい.

ファイル中の幾つかのデータを消してしまいたい場合があります.plot時 にデータのスキップを指定するには every を使 う方法と,データファイルを直接編集する方法があります.ここでは編集 する方法を説明します.スキップしたい数値の前に,何か適当な文字(例えば "?"等)を入れると,そこは読み飛ばされます.勿論,数値自体を文字で置き換 えても構いません.本当は,データを読み飛ばずための文字は, set missing で指定された文字の筈なのですが,数字に変換出来ない文字な らなんでも良いようです.

下の2つの例の様に,(X,Y1)と(X,Y2)のグラフを描く場合を考えます.

test1.dat test2.dat
#  X     Y1    Y2
   1.0   1.2   1.5
  ?2.0   1.8   0.8
   3.0   1.6   1.1
#  X     Y1    Y2
   1.0   1.2   1.5
   2.0   1.8  ?0.8
   3.0   1.6   1.1

左の例ではX座標に?が付いていおり,2番目のデータである(2.0,1.8)と (2.0,0.8)の2つの点が読み飛ばされます.右の例では(2.0,1.8)の組は生きて おり,(2.0,0.8)だけが消されます.

gnuplot> plot "test1.dat" using 1:2 with linespoints,\
              "test1.dat" using 1:3 with linespoints
fig/sample7.5a
gnuplot> plot "test2.dat" using 1:2 with linespoints,\
              "test2.dat" using 1:3 with linespoints
fig/sample7.5b

この機能は,データが表形式になっているときに,各カラムでの表示範囲 を変えたい場合に便利です.例えば,次のようなデータがあり,このY1,Y2を 同時に対数プロットする場合を考えます.

#  X     Y1    Y2
   1.0   0.0   0.1
   2.0   0.0   0.1
   3.0   0.0   0.1
   4.0   0.1   0.2
   5.0   0.6   0.4
   6.0   1.0   0.9
   7.0   1.2   1.7
   8.0   1.3   2.4

Y1はXが[1:3]の範囲で0なので対数にはなりません.gnuplotはこの場合, プロット出来る最後の点(ここではX=4)から下に真直な線を引きます.

fig/sample7.5c

この鉛直線を消すには,Y1=0.0の部分にプロット出来ない文字を書き込み ます.例えばゼロの部分を "?0.0" に変えてプロットすると,Y1のデータ(赤 い線)はX=4から始めることができます.同様のことは,plotコマンドで, every ::3 を指定しても出来ます.

fig/sample7.5d

ファイルの一部だけをプロットしたい.

データファイル中で,プロットするデータの範囲(データファイル中の行)を 指定するには,plotコマンドでeveryというキーワードを使います. 例えば plot "test.dat" every 2 なら一行おきにプロットします.

データファイルが1行の空行で区切られた幾つかのデータブロックに分かれている 場合も,everyによってデータブロックの読み飛ばしを指定できます. every :2 ならデータブロックを一つおきにプロットします.

every I:J:K:L:M:N
I 行の増分
J データブロックの増分
K プロット開始行
L プロット開始データブロック
M プロット終了行
N プロット終了データブロック
every 2 1行おきにプロットする
every ::3 最初の3行を飛ばしてプロットする
every ::3::5 4行目から6行目までをプロットする
every ::0::0 最初の行だけをプロットする
every 2::::6 最初の7行を1行おきにプロットする
every :2 1データブロックおきにプロットする
every :::5::8 5から8データブロックをプロットする

データファイルの最初や最後の数行だけを切り出して 表示するだけなら(そして使っている環境がunix系のものであれば),以下のよう にunixのコマンド "head" や "tail" を使うこともできます.

gnuplot> plot "< head -10 test.dat" using 1:2 with lines
gnuplot> plot "< tail -3 test.dat" using 1:2 with lines
gnuplot> plot "< head -5 test.dat" using 1:2 with lines,\
>        plot "< tail -5 test.dat" using 1:2 with points

1行目のplot例ではデータファイル "test.dat"の最初の10行だ けをプロットします.2行目はデータファイルの最後の3行だけを表示するもの です.4,5行目は同じファイルの最初と最後の5行づつ,最初は線で,後の5点 は記号で表示することを表します.

from an Iwata-kun's question. Thanks !
up