Gnuplotを使ったグラフ 作成


  1. 関数を描画
  2. データファイルからデータを描画
    1. とりあえずプロットしてみる
    2. 描画する列を指定
    3. 線で描画
    4. 複数データを同時にプロット
      1. 線の色,太さを指定
      2. プロットに名前をつける
    5. データを間引いて描画
      1. (おまけ)予めダウンサンプルしたファイルを作っておく方法 (Octave使用)
      2. (おまけ)デジタルフィルタを通す
    6. プロットをファイルに出力
      1. epsファイルへ出力
        1. epsからPDFへ変換
        2. epsからPNGへ変換
      2. epsファイルへ出力(論文用モノクロ)
      3. enhancedモードで(ファイルでなく)画面 に出力する.
      4. PNGファイルへ出力
    7. 軸の設定
      1. 描画範囲の指定
      2. Logで描画
      3. 軸タイトルの表示
        1. よりきれいなグラフをかくために
      4. 軸目盛のフォーマット
      5. π単位でデータをプロット
    8. 複数軸のプロット
    9. 読み込んだデータに演算を施してプロット
    10. 凡例の設定
    11. 関数フィッティング
      1. 関数のプロット範囲を制限する
    12. グラフ内に図形を描画
    13. エラーバーの追加
    14. 3次元グラフ
  3. コマンドファイルを予め用意して一括実行
  4. CのプログラムからGnuplotを使う






関数を描画



データファイルからデータを描画

サンプルデータファイル:dummy.dat
サンプルデータファイルは,
0, 0.8049510453688615, 2.31952283024357e-15, 0.7605599193272974, 0.04439112604156179
0.005005005005005005, 1.557789016802632, 2.948218020374285e-15, 0.7673488725092119, 0.7904401442934171
0.01001001001001001, 2.645163332931182, 3.74431527665693e-15, 0.7741811869528665, 1.870982145978312
0.01501501501501501, 2.590863861246925, 4.751569563142984e-15, 0.7810569431200902, 1.80980691812683
    :
のように,x, y1, y2, y3のデータがカンマ区切りで羅列されている.

gnuplotで読み込むときのデータ区切り記号変更は,
set datafile separator ","
等で変更できる.

データファイルに1行の空行が入るとブロック区切り,2行の空行が入るとデータセットの区切りになる.
たとえば,dat-multiblock.txt
1    -4       1つめのデータセットの 中のブロック1
2    -3
    :
10    5
                [空行]
1    1       1つ目のデータセットのブロック2
3    9
    :
15    225
              [空行]
2    1.4142135624       1つ目のデータセットのブロック3
4    2
    :
14    3.7416573868
                 [空行]
                 [空行]
1    4          2つめのデータセットのブロック1
2    5
    :
10    13
みたいな感じ

とりあえずプロットしてみる

まずは,
plot "dummy.dat"
としてみる.
すると,



みたいに,xとy1のデータがプロットされる.

描画する列を指定

プロットしたいデータ列を指定する場合は,
plot "dummy.dat" using 1:3
みたいにすると,X軸に1列,Y軸に3列をプロットできる.
ちなみに,上のコマンドは次のように省略してかける.
plot "dummy.dat" u 1:3



XとY軸を入れ替えたければ,
plot "dummy.dat" u 2:1
とすれば,横軸にY1,縦軸にXを描画できる.



線で描画

データ間を線で結んで描画する場合は,
plot "dummy.dat" u 1:2 with lines
もしくは,
plot "dummy.dat" u 1:2 w l
とする.



複数データを同時にプロット

plot "dummy.dat" u 1:2 w l,  "dummy.dat" u 1:3 w l,  "dummy.dat" u 1:4 w l
もし,長くなって複数行に書く場合は,行末に"\"を書く
plot "dummy.dat" u 1:2 w l,  \
"dummy.dat" u 1:3 w l,  \
"dummy.dat" u 1:4 w l
また,同じデータファイルを使うなら,2回目以降はファイル名を省略できる.
plot "dummy.dat" u 1:2 w l,  \
"" u 1:3 w l,  \
"" u 1:4 w l



線の色,太さを指定

線の色を変える場合は,lc (Line Color)もしくは lt (Line Type)オプションを指定する.
線の太さはlw (Line Width)で指定する.
 plot "dummy.dat" u 1:2 w l   lt 1 lc 3 lw 0.5,  \
"" u 1:3 w l lt 3 lc 4  lw 5, \
"" u 1:4 w l lt 0 lc 1 lw 2.5


lc, ltの後にくる数字がどの線種,色に相当するかは,本やWebを参照する.
(このページにも今後追加するかも)


ちなみに,シンボル(丸とか四角とか)でプロットする場合も,同様にpt (Point Type)なんかで形を指定できる.
w p( = with point)でシンボルでプロットする.
ps(Point Size)でシンボルの大きさを指定する.
 plot "dummy.dat" u 1:2 w p   lc 3 ps 0.5 pt 4,  \
"" u 1:3 w p  lc 4  ps 1.2 pt 5, \
"" u 1:4 w p  lc 1 ps 1.5 pt 6


プロットに名前をつける

凡例に表示される名前を変更するためには,title "文字列" を指定する.
notitleを指定すると,凡例に表示されなくなる.
plot "dummy.dat" u 1:2 w l   lt 1 lc 3 lw 0.5  title "exp data",  \
"" u 1:3 w l lt 3 lc 4  lw 5 title "peak 1", \
"" u 1:4 w l lt 0 lc 1 lw 2.5 notitle




データを間引いて描画

もしデータ点数が多すぎて,プロットに時間がかかる場合は,間引いて表示するとスムーズになる.
必要があれば,最終的な出力の時のみ,全点プロットすれば作業が効率的
set term postscript enhanced size 4,3 font "Times,16"
set out "test.eps"
set xlabel "{/=16 {/Times-Italic=16 t} [s]}"
set ylabel "{/=16 Intensity [A.U.]}"
plot "dummy.dat" u 1:2 w l title "Raw", \
    ""every 10:1:0:0::0 u 1:2 w l lt 1 lc 3 lw 2 title "Downsampled"

もしくは
plot "dummy.dat" u 1:2 w l title "Raw", \
    ""every 10 u 1:2 w l lt 1 lc 3 lw 2 title "Downsampled"


every の後には,読み飛ばしたいスキップ数,開始,終了番号を設定する.
every [読み飛ばす行ステップ数] : [読み飛ばすブロック数] : [開始行] : [開始ブロック番号] : [終了行] : [終了ブロック番号]

指定しない場合は省略もできる(上の例でも終了行は省略している)



容易に推測できるように,everyオプションを使うことで,データの一部のみをプロットすることもできる.
 plot "dummy.dat" every 3:1:100::500 u 1:2 w l title "Partial data"





(おまけ)予めダウンサンプルしたファイルを 作っておく方法(Octave使用)

Octaveを起動して
dat=load("dummy.dat");
t=dat(:,1);
y1=dat(:,2);
y2=dat(:,3);
y3=dat(:,4);
等でデータを読み込む.

y1_ds=downsample(y1,10);
で,データ数を1/10に間引く.
x軸も同様に間引く
t_ds=downsample(t,10);

保存は,
dlmwrite("dummy-ds.dat", [t_ds, y1_ds], ", ");
とすると,"dummy-ds.dat"に,t_ds, y1_ds をカンマ区切りで出力できる.

gnuplotで表示すると,
set term postscript enhanced size 4,3 font "Times,16"
set out "test.eps"
set xlabel "{/=16 {/Times-Italic=16 t} [s]}"
set ylabel "{/=16 Intensity [A.U.]}"
plot "dummy.dat" u 1:2 w l title "Raw", "dummy-ds.dat" u 1:2 w l lt 1 lc 3 lw 2 title "Downsampled"



(おまけ)デジタルフィルタを通す

Octaveを使う.
Octaveを起動して
dat=load("dummy.dat");
t=dat(:,1);
y1=dat(:,2);
y2=dat(:,3);
y3=dat(:,4);
等でデータを読み込む.
次に,
coeff = fir1(63, 0.1, 'low', hamming(64));
でフィルタの係数を計算する.
最初の引数 "63" は "タップ数 - 1",次は規格化カットオフ周波数,'low'はLPFを意味する, hamming(64)は窓関数

ちなみに,
freqz(coeff, 1, 1000)
または
freqz(coeff, 1, 1000, "half", 1e5)
で,周波数特性を表示できる.

 y_filt=filter(coeff,1,y1)
でデジタルフィルター(FIR)を通した波形が得られる.

dlmwrite("dummy-fir.dat", [t,y1,y_filt], ", ");
で,ファイル"dummy-fir.dat"にデータ t, y1, y_filt を書き込む.
この時のデータ区切りは", ".

このデータをGnuplotでプロットすると,下のようになる.

set term postscript enhanced size 4,3 font "Times,16"
set out "test.eps"
set xlabel "{/=16 {/Times-Italic=16 t} [s]}"
set ylabel "{/=16 Intensity [A.U.]}"
plot "dummy-fir.dat" u 1:2 w l title "Raw data", "" u 1:3 w l lt 1 lc 3 title "Filtered"


FIRフィルタ(LPF)を通すことで,図のように高周波成分をカットできる.
ただし,タップ数分だけ遅れることに注意する.


プロットをファイルに出力

論文やプレゼンで使う場合には,グラフをファイルに出力する必要がある.
また,後述のenhancedモードを設定することで,軸目盛等をきれいに書くことができる.

epsファイルへ出力

set term postscript eps enhanced size 4.0,3.0 font "Times,16"
とすると,enhancedモード,サイズ 4x3インチ,Timesフォント(サイズ16)のEPSファイルに出力される.
 次に,いかのようにファイル名を指定する.
set out "test.eps"

epsからPDFへ変換

Texなんかの場合はこのepsを直接読み込むか,pdfに変換してから読み込む.
epspdf  test.eps

epsからPNGへ変換

ラスター画像(jpg,pngなど)にする場合はImagemagickを使う.
convert -density 400 test.eps  test.png
-density で出来上がる画像の解像度が変わる.

epsファイルへ出力(論文用モノクロ)

set terminal postscript eps dashed monochrome size 4.0,3.0 enhanced font "Times,16"
set output "test-mono.eps"


enhancedモードで(ファイルでなく)画面 に出力する.

set term X11 enhanced font "Times,16"


PNGファイルへ出力

 set term png enhanced font "Times,16"



各出力方法によって,出来栄えが異なるので,自分で確かめてみると良い.
おすすめはEPS出力.
PNGファイルが欲しければ,EPSで出力してからPNGに変換するほうが美しいグラフがかける.


軸の設定

描画範囲の指定

set xrange [0.5:3]
set yrange [0:20]
等で,X,Yそれぞれの描画範囲を [最小 : 最大] で指定できる.



範囲を自動で決めたい場合は,"*"を使う.たとえば,Y軸の下限だけ設定して,上限は自動にしたい場合は,
set yrange [0:*]
とする.

Logで描画

set log x
等.リニアに戻すには,
unset log x


軸タイトルの表示

set xlabel offset 0,0.5 "f0 [Hz]"
などとすれば,ラベルに名前をつけることができる.

よりきれいなグラフをかくために

enhancedモードを使えば,様々な修飾をしたり,フォントをかえたりできる.
set term postscript eps enhanced font "Times,16"
set out "test.eps"
set xlabel offset 0,0.5 "{/=16 {/Times-Italic=16 f}_0 [Hz]}"
set ylabel offset 0,0  "{/Symbol-Oblique=16 q}"
すると,test.epsというファイルができる.


フォントを変える場合は, ”{/Times-Italic=16  freq. }"みたいに{}で囲む.
"/Times-Italic"の部分がフォント名,"=16"の部分がフォントサイズになる.
デフォルトで良い場合は省略できる.
例えば,サイズだけ変えたいなら,"{/=16  Freq.}"とかでよいし,フォントだけ変えたいなら"{/Times  Freq.}"でよい.

/Times
/Times-Italic
/Symbol
/Symbol-Oblique    (シンボルの斜体)

あたりがよく使う.
出力先によっては,うまく表示できないこともあるので注意.
EPS出力なら大抵うまく行く

軸目盛のフォーマット

set format x "%4.1f"
とすると,X軸の目盛の数値を,全体で4桁,小数点以下1桁で表示する.


set xtics 0, 2.0 nomirror
とすると,X=0から,2.0おきに目盛を書く.
nomirrorとすると反対側(X軸(下側)なら,上側の軸)に目盛線を書かないようにする.
また,
set mxtics 5
とすると,副目盛の数をしていできる.
上の例だと,主目盛りの間に5個の副目盛を書く.



目盛線の長さを変えるには,
set xtics 0, 2.0 nomirror scale 3, 1
とすると,下のように主目盛りの長さ3,副目盛の長さ1になる.



π単位でデータをプロット

角度データ(ラジアン単位)をプロットする場合は,π単位でプロットしたい.
以下のようにすると,簡単に実現できる.

set yrange[0: pi*6]
set format y "%.1P {/Symbol p}"
set ylabel offset 2.5,0 "{/Symbol=16 Q} [rad]" font "Times,16"
set ytics 0, pi*0.25, 6pi nomirror font "Times,16"
set mytics 2





複数軸のプロット

複数のデータをプロットする場合に,データレンジが全くことなるデータをプロットする場合は,軸を変えるとみやすい.
上でこれまでに説明したやり方とほとんど同じで,名前"y"を"y2"に変えれば,副軸の設定ができる.
たとえば,
set y2tics -4.0, 2.0 scale 3,1 nomirror
set y2range[-4.0:4.0]
set my2tics 5
set format y2 "%3.2f"
set y2label offset -2.5,0 "{/Symbol=16 D}{/Times_Italic=16 f} [Hz]" font "Times,16"
とうで,副軸(右の縦軸)の設定をする.
プロットは,
plot "dummy.dat" u 1:2 w l  lt 1 lc 3 lw 0.5  axes x1y1  title "exp data",  \
"" u 1:3 w l lt 3 lc 4  lw 5 axes x1y1  title  "peak 1", \
"" u 1:4 w l lt 0 lc 1 lw 2.5 axes x1y1  notitle, \
"" u 1:5 w l lt 1 lc 1 lw 0.2 axes x1y2  title "noise"
のように,axesオプションでどの軸を使うかをしていする.
x1y1は,下軸と左軸を使用,x1y2は下軸と右軸を使用等.



読み込んだデータに演算を施してプロット

読み込んだデータに演算を施してプロットすることができる.
plot "dummy.dat" u ($1*10+3):(log($2)) w l title "data"
$1, $2等が,データファイルから読み込んだ1列,2列目のデータを意味する.
演算は,上のように四則演算のほかに,Log, Sinなども使える.






凡例の設定

凡例の書式や位置を変更する.

set key Left samplen 2 reverse at 4.8,15

Righe (Left)で文字の右端(左端)をそろえる
reverse で凡例線と文字の位置を入れ替える
sampleで凡例線の長さを指定
at で挿入位置(凡例の右上の座標)を指定する




関数フィッティング

gnuplotを使って関数フィッティングができる.
まず,関数を定義する.
今の例の場合は,2つのGaussian関数を使ってフィッティングさせてみる.
まずは,関数を定義する.
f1(x) = a1*exp( -((x-b1)/c1)**2)
f2(x) = a2*exp( -((x-b2)/c2)**2)
f3(x) = f1(x) + f2(x) + ost

次に,変数の初期値を設定する.
複雑な関数の場合には,初期値にある程度妥当(最終値に近い)な値を入れないと,正しい結果が得られない.
そこで,だいたい正しそうな初期値を設定しておく.
a1=15
b1=1.5
c1=1
a2=5
b2=2
c2=2
ost=1

次のコマンドでフィッティングが始まる
fit [0:4] f3(x) "dummy.dat" u 1:2  via a1,a2,b1,b2,c1,c2,ost
ここでは,X軸の範囲が0~4で,データ"dummy.dat"の1列と2列を使い,変数a1, a2, b1, a2, c1, c2をパラメータにしてフィッティングする.
u 1:2のところを u 1:2:5等とすれば,フィッティングの際に重みづけすることができる.

フィッティング結果は,以下のように表示される.Final set of parameters            Asymptotic Standard Error
Final set of parameters            Asymptotic Standard Error
=======================            ==========================

a1              = 9.83033          +/- 0.1001       (1.018%)
a2              = 4.48751          +/- 0.1581       (3.522%)
b1              = 1.497            +/- 0.00197      (0.1316%)
b2              = 1.96693          +/- 0.01184      (0.6022%)
c1              = 0.245252         +/- 0.00313      (1.276%)
c2              = 1.42212          +/- 0.05717      (4.02%)
ost             = 1.15613          +/- 0.1722       (14.9%)

フィッティングの結果は変数に自動的に代入される.

フィッティング結果を見るには,データと同時に関数もプロットすればよい
plot "dummy.dat" u 1:2 w p  lc 3 ps 0.5 pt 4, \
   f3(x) lt 2 lc 1 lw 2.5, \
   f1(x) lt 3 lc 4 lw 1, \
   f2(x) lt 3 lc 3 lw 1, \
   ost lt 3 lc 5 lw 1 title "offset"




関数のプロット範囲を制限する

上の方法だと,関数はX軸の全ての範囲にプロットされる.
場合によっては,一部だけ表示したい場合もある.
たとえば,X軸の範囲によって,近似曲線が異なる場合など.例:dat-DoubleLinear.txt

f1(x) = a1*x + b1
f2(x) = a2*x + b2
fit [0:5] f1(x) "dat-DoubleLinear.txt" u 1:2 via a1,b1
fit [5:10] f2(x) "dat-DoubleLinear.txt" u 1:2 via a2,b2

ここで,plotすると,
plot "dat-DoubleLinear.txt" w p pt 4, f1(x) w l lt 1 lc 1, f2(x) w l lt 1 lc 3

となって,フィッティングした範囲外にも直線が引かれてかっこ悪い.
そこで,3項演算子を使って描画範囲を調整する.
3項演算子は  (式) ? (真の時の値): (偽の時の値)という感じでかく.

set term postscript eps enhanced
plot "dat-DoubleLinear.txt" w p pt 4
replot (x<=5 ? f1(x) : 1/0) w l lt 1 lc 1
replot (x>=5 ? f2(x) : 1/0) w l lt 1 lc 3
set out "test.eps"
replot

上の3行目で x<5 の時は f1(x)をプロットし,それ以外の場合は 1/0で零除算なので何も描画されなくなる.
全ての関数を描画してから,出力ファイルを指定( set out "***")し,最後にreplotすることでファイルに出力する.
(関数のreplotの前にset outしてしまうと,複数ページのepsが出力されてしまう.)



グラフ内に図形を描画


エラーバーの追加


3次元グラフ


グラフの大きさを変更する



コマンドファイルを予め用意して一括実行

これまでに説明したコマンドは,いちいち全部キーボードで入力しなくても,テキストファイルに書いておいて,読み込むことができる.
gnuplotを使う大きなメリットの1つである.
つまり,沢山グラフを書くときに,大きさや軸の設定などを複数のグラフで揃えるのがとても楽.
例えば,Gnuplot-command.txt のようなファイル を作成する.

set term postscript eps enhanced size 4.0,3.0 font "Times,16"
set out "test.eps"

# Common setting for both X and Y axis
set tics font "Times,16" scale 3,1

# X-axis
set xlabel offset 0,0.5 "{/=16 {/Times-Italic=16 f}_0 [Hz]}"
set format x "%4.1f"
set xrange [0:5]
set xtics 0,1 nomirror
set mxtics 5

# Y-axis
set ylabel offset 0,0  "{/Symbol-Oblique=16 q}"
set format y "%4.0f"
set yrange [0:16]
set ytics 0,2 nomirror
set mytics 5

#Legend
set key Left samplen 2 reverse at 4.5,15

#Function Fitting
f1(x) = a1*exp( -((x-b1)/c1)**2)
f2(x) = a2*exp( -((x-b2)/c2)**2)
f3(x) = f1(x) + f2(x) + ost

a1=15
b1=1.5
c1=1
a2=5
b2=2
c2=2
ost=1

fit [0:4] f3(x) "dummy.dat" u 1:2  via a1,a2,b1,b2,c1,c2,ost

plot "dummy.dat" u 1:2 w p  lc 3 ps 0.5 pt 4, \
   f3(x) lt 2 lc 1 lw 2.5, \
   f1(x) lt 3 lc 4 lw 1, \
   f2(x) lt 3 lc 3 lw 1, \
   ost lt 3 lc 5 lw 1 title "offset"

gnuplot内で,
load "Gnuplot-command.txt"
のように呼び出すか,シェルから,
gnuplot Gnuplot-command.txt
のように引数としてコマンドファイルを指定してgnuplotを実行する.


CのプログラムからGnuplotを使う