データファイルのプロット
基本
Gnuplot は次のような形式のテキストデータをプロットすることもできます。 実験データのプロットなど、こちらのほうが応用範囲が広いでしょう。
# SOI index 1935.500 0.2 1935.583 0.1 1935.667 0.1 …
データファイルのフォーマットは次のようになっています。
- シャープ記号 # ではじまる行はコメント行で、無視されます。
- 点の座標(x 座標と y 座標の値)を1つ以上の空白ではさんで指定します。
サンプルデータを作業ディレクトリにコピーしてプロットしてみましょう。 まず、ターミナルで次のコマンドを実行します。
$ cp ~mtkg/soi_anom.dat ./
Gnuplot の plot
コマンドでプロットします。
gnuplot> plot "soi_anom.dat"
データファイルをプロットする際のデフォルトのスタイルは points です。 別のスタイルを指定するには with オプションを使います。
gnuplot> plot 'soi_anom.dat' with linespoints (または w lp) 点を線で結ぶ gnuplot> plot 'soi_anom.dat' with lines (または w l) 線で結ぶ(点は描かない) gnuplot> plot 'soi_anom.dat' with impulses (または w i)
using オプション
今度はもっとたくさんデータがある場合を考えてみましょう。 trig.dat は三角関数の表になっており、データが x, sin(x), cos(x), tan(x) の順に並んでいます。
# X SIN(X) COS(X) TAN(X) 0.00000E+00 0.00000E+00 0.10000E+01 0.00000E+00 0.17453E-01 0.17452E-01 0.99985E+00 0.17455E-01 0.34907E-01 0.34899E-01 0.99939E+00 0.34921E-01 0.52360E-01 0.52336E-01 0.99863E+00 0.52408E-01 … … … …
ターミナルで次のコマンドを実行し、データファイルを自分の作業ディレクトリにコピーしてください。
$ cp ~mtkg/trig.dat ./
plot コマンドで trig.dat をプロットすると sin(x) のグラフが表示されます。 with line オプションを使うとデータ点が直線で結ばれて表示されます。
gnutplot> plot "trig.dat" gnutplot> plot "trig.dat" with line (または w l)
using オプションを使うと3列目や4列目のデータをプロットすることができます。
using (x座標とする列番号):(y座標とする列番号)
cos(x) をプロットするには1列目の値を x 座標、3列目の値を y 座標にすればよいので、using 1:3
とします。
gnuplot> plot "trig.dat" using 1:3
cos(x) の値を x 座標、sin(x) の値を y 座標にするとどんなグラフになるでしょうか? 次のコマンドを試してみてください。
gnuplot> plot "trig.dat" using 3:2
データの値の参照
$1
, $2
, …という表記方法を使うと using オプションの中でデータの値を参照することができます(数字はデータの列番号)。
sin(x)/x のグラフをプロットするは、xの値(1列目の値)に対して「2列目の値÷1列目の値」をプロットすればよいので、次のように書けば OK です。
gnuplot> plot "trig.dat" using 1:($2/$1)
$1
, $2
という表記を使う場合は (…) で式をくくってやる必要があります。
練習問題
(x*cos(x), x*sin(x))
の軌跡をプロットせよ。
解答:
x*cos(x)
は $1*$3
,
x*sin(x)
は $1*$2
となります。
したがって、次のコマンドでプロットすることができます。
gnuplot> plot "trig.dat" using ($1*$3):($1*$2) w l
図をファイルに出力する
絵をファイルに出力するには set terminal
コマンドと
set output
コマンドを使います。
set terminal 画像フォーマット(形式)を設定する set output 出力する画像ファイルの名前を設定する
多くの画像フォーマットに対応していますがよく使われるのは
- GIF
- JPEG
- PostScript, EPS (Enhanced PostScript)
- PDF (Portable Document Format)
などでしょう。 GIF や JPEG 形式にしておくと Word などの文書にグラフを貼付けることができます。 EPS は PostScript (PS) という画像形式の一種で、拡大してもグラフがギザギザにならないという特徴があります (このような画像形式をベクター形式といいます)。 そのため出版業界などで多く使われています。
sin(x)
のグラフを sin_x.gif
というファイルに出力するには次のようにします。
注意:gnuplot>
は gnuplot のプロンプトで、入力する必要はありません。
gnuplot> set terminal gif ! フォーマットを GIF にセット gnuplot> set output "sin_x.gif" ! ファイル名をセット(ファイル名は "…" で囲む) gnuplot> plot sin(x)
同じグラフを EPS 形式で出力してみましょう。
ファイル名は sin_x.eps
にします。
gnuplot> set terminal postscript eps gnuplot> set output "sin_x.eps" gnuplot> replot
画像を画面に表示するには display
コマンド(gif, jpeg の場合)や
gv
コマンド(PS, EPS の場合)を利用します。
別のターミナルから次のコマンドを打ち込んで画像ファイルを表示してみましょう。
$ display sin_x.gif $ gv sin_x.eps
Gnuplot の出力先をディスプレイに戻すには terminal
に wxt
を指定します。
(terminal が wxt の場合、output の設定は無視されます。)
gnuplot> set terminal wxt gnuplot> replot
Postscript のオプション
terminal
として postscript eps
を利用する場合は、オプションで文字の大きさを変更することができます。
gnuplot> set terminal postscript eps "Helvetica" 28
とすればフォントを Helvetica (一般的に使われるゴシック体フォント)とし、文字の大きさを 28 ポイントに変更できます。
関数・定数の定義
Gnuplot では自分で関数や定数を定義することができます。
関数定義の例:
# 1変数の関数 a = 1.0 b = -2.0 f(x) = a * x + b g(x) = f(x) * (x-1) # 2変数の関数 h(x, y) = f(x) * exp(-y*y) cn(n, x) = cos(n*x) # 多変数の関数 ndist(x, mu, sigma) = exp(-(x-mu)**2/(2*sigma**2)) / sqrt(2*pi*sigma**2)
実際に f(x) = sin(x) / x
という関数を定義して、グラフをプロットしてみましょう。
gnuplot> f(x) = sin(x) / x gnuplot> plot f(x)
三項演算子
関数の定義に場合分けが必要になることがあります。 このような場合には
f(x) = 条件式 ? 式1 : 式2
という書き方を使います。
?
という演算子は「条件」, 「式1」, 「式2」の3つの要素を取るので「三項演算子」と呼ばれます。
f(x)
の値は、「条件式」が成り立つ場合(真である場合)は式1、成り立たない場合(偽である場合)は式2となります。
例えば、f(x) = |x|
を定義するには
f(x) = x (x >= 0) -x (x < 0)
という場合分けが必要です。 したがって、この関数の定義は
f(x) = (x >= 0) ? x : -x
となります。
実際にこの f(x)
を定義してグラフをプロットしてみましょう。
条件式の中で使える演算子には次のようなものがあります。
< より小さい > より大きい <= 以下 >= 以上 == 等しい != 等しくない && かつ(論理積) || または(論理和) ! 否定
三項演算子の入れ子
三項演算子を入れ子にするともっと複雑な場合分けを表現することができます。
g(x) = -1 ( x < -1) x (-1 <= x < 1) 1 ( 1 <= x )
という関数を定義するには
x = -1
での大小判定と
x = 1
での大小判定を組み合わせればよいでしょう。
gnuplot> g(x) = (x < -1) ? -1 : (x < 1) ? x : 1 -------- -- --------------- 条件 式1 式2
この例では「式2」にあたる部分が三項演算子の式「(x <= 1) ? x : 1
」となっています。
実際に g(x)
を定義してグラフをプロットしてみましょう。
gnuplot> plot [-5:5] [-2:2] g(x)
漸化式
漸化式で表される式も簡単に定義することができます。
次のような関数列の和 S(n,x)
を考えてみましょう。
S(n, x) = cos(x) + cos(2*x) + cos(3*x) + ... + cos(n*x)
S(n, x)
は次のような漸化式で表すことができます。
S(1, x) = cos(x) S(n, x) = S(n-1, x) + cos(n*x) (n >= 2)
これを Gnuplot で定義するには次のようにします。
gnuplot> S(n, x) = (n >= 2) ? S(n-1, x) + cos(n*x) : cos(x)
次のように書いてもよいでしょう。
gnuplot> S(n, x) = (n == 1) ? cos(x) : S(n-1, x) + cos(n*x)
S(n, x)
はデルタ関数という関数に収束します。
次のようにプロットして様子を観察してみましょう。
gnuplot> set samples 2000 gnuplot> plot [-pi:pi] S(1, x), S(3, x), S(10, x) gnuplot> plot [-pi:pi] S(10, x), S(30, x), S(100, x)
媒介変数表示(2次元)
原点 O を中心とする半径 1 の円を考え、円上に点 P を取ります。 OP ベクトルと +x 軸とのなす角を t とすると、点 P の座標は
x 座標の値 = cos(t) y 座標の値 = sin(t)
と表せます。 t を 0 から 2π まで変化させながらプロットすれば円のグラフが得られます。 このように、点の x 座標と y 座標の値を別の変数 t で表す方法を「媒介変数表示」といいます。
媒介変数表示でグラフをプロットするには set parametric
コマンドを使います。
gnuplot> set parametric gnuplot> plot [0:1.5*pi] cos(t), sin(t) gnuplot> set size square gnuplot> replot
(cos(t)*t, sin(t)*t)
をプロットすれば螺旋になりますね。
gnuplot> plot [0:10*pi] cos(t)*t, sin(t)*t
媒介変数モードをやめるには unset parametric
とします。
媒介変数表示(3次元)
媒介変数モードで splot
コマンドを使うこともできます。
この場合は媒介変数が u
, v
の2つになります。
球面
球座標を使うと半径 1 の単位球面上の点の座標は次のように表せます。
x 座標の値 = cos(u)*cos(v) y 座標の値 = sin(u)*cos(v) z 座標の値 = sin(v)
ここで u
は余緯度、v
は経度です。
余緯度というのは位置ベクトルが +z 軸(北極の方向)となす角度のことで、「π/2 - 緯度
」に等しくなります。
したがって、余緯度の値は北極で 0 (0度)、赤道で π/2 (90度)、南極で π (180度) となります。
gnuplot> set parametric gnuplot> set isosample 48, 24 gnuplot> splot cos(u)*cos(v), sin(u)*cos(v), sin(v)
次のウェブページが参考になります。
トーラス
媒介変数表示を使ってトーラス(ドーナツ型)を描いてみましょう。
gnuplot> set parametric gnuplot> splot cos(u)*(3+cos(v)), sin(u)*(3+cos(v)), sin(v)
マウスでグラフをドラッグして視点を動かすことができます。
3次元曲線
2つの媒介変数 u
, v
のうち、一方のみを使うことで、3次元曲線をプロットすることができます。
gnuplot> set isosample 200 gnuplto> splot [0:10*pi] u*cos(u), u*sin(u), u
ファイルからの読み込み / ファイルへの書き込み
load
コマンドを使うと関数の定義やコマンドをファイルから読み込むことができます。
次のような内容のファイル (plot.gp
) を Emacs で作成し、Gnuplot から読み込んでみましょう。
g(x)
の定義にある行末の \
(バックシュラッシュ)は継続行を表します。
# # (半角シャープ)で始まる行はコメント行として無視される # 関数の定義 a = 1.0 b = -3.0 c = 2.0 f(x) = a * x**2 + b * x + c g(x) = (x < -1) ? 0 : \ (x < 1) ? 10 : 0 # グラフのタイトル set title "plot of f(x) and g(x)" # f(x), g(x) のプロット plot [-pi:pi] f(x), g(x)
ファイルができたら Gnuplot から読み込んでみましょう。
gnuplot> load "plot.gp"
save
コマンドを使うと現在の状態(関数や変数の定義など)をファイルに保存することができます。
作業を途中で中断するときなどに便利でしょう。
gnuplot> save "hozon.gp"
本日の課題
1. データファイルのプロット
- trig.dat を使って
(cos(x)**3, sin(x)**3)
の軌跡を描け。 - trig.dat を使って
(cos(x)**1, sin(x)**5)
の軌跡を描け。
1. 条件分岐 (1)
次のような関数(階段関数・ステップ関数)を定義してプロットせよ。
step(x) = -1 (x < 0) 1 (x >= 0)
さらに、グラフを "step.jpg" という名前でファイルに出力せよ。
2. 漸化式
単位ステップ関数 step(x) は sin(x), sin(3*x), sin(5*x), …を使って次のように展開される。 (これをフーリエ展開という。)
4 sin(3*x) sin(5*x) 4 ∞ sin((2*n-1)*x) step(x) = ---- [sin(x) + -------- + -------- + ...] = ---- Σ ---------------- π 3 5 π n=1 (2*n-1)
右辺の第 n 項までの和を表す関数を S(n,x)
とすると
S(n,x)
は次の漸化式で定義できる。
S(1, x) = (4/pi) * sin(x) S(n, x) = S(n-1, x) + (4/pi) * sin((2*n-1)*x) / (2*n-1) (n >= 2)
Gnuplot の関数として S(n, x)
を定義し、
S(1, x)
,
S(3, x)
,
S(9, x)
,
S(27, x)
を重ねて (-2π, 2π)
の範囲でプロットせよ。
3. 条件分岐 (2)
次のような関数 saw(x)
を定義してプロットせよ。
saw(x) = 0 ( x < -1) 1+x (-1 <= x < 0) 1-x ( 0 <= x < 1) 0 ( 1 <= x )
継続行をうまく使うと、三項演算子の入れ子をきれいに書くことができる。 (\ の直後で改行すること。# より右はコードの説明なので不要。)
saw(x) = (x < -1) ? 0 : \ # x < -1 なら 0, x >= -1 なら次の行へ (x < 0) ? 1+x : \ # x < 0 なら 1+x, x >= 0 なら次の行へ (x < 1) ? 1-x : 0 # x < 1 なら 1-x, x >= 1 なら 0
関数定義が長くなる場合は、ファイルに関数定義を記述し、load
コマンドで読み込むとよい。
別解:
絶対値関数 abs(x)
を使うと簡単に書ける。
saw(x) = (abs(x) < 1) ? 1-abs(x) : 0
4. 三項間漸化式
n 次のルジャンドル多項式 P(n, x)
は次の漸化式で定義される。
P(0, x) = 1 P(1, x) = x P(n, x) = ( (2*n-1)*x*P(n-1,x) - (n-1)*P(n-2,x) ) / n (n >= 2)
P(n, x)
を定義し、(-1, 1)
の範囲で
P(0, x)
,
P(1, x)
,
P(2, x)
,
P(3, x)
,
P(4, x)
を重ねてプロットせよ。
y 軸の表示範囲は [-1.5:1.5]
程度にするとよい。
ヒント:三項演算子を入れ子にすればよい。 この例では「式2」のところで n = 0, 1 の場合を処理している。
P(n,x) = (n >= 2) ? ((2*n-1)*x*P(n-1,x)-(n-1)*P(n-2,x))/n : (n == 1) ? x : 1 <------> <-----------------------------------> <--------------> 条件 式1 式2
Emacs のメモ
Emacs でファイルを作成する手順は次のようになります。
C-x C-f
でファイル名を入力する- ファイルを編集する
C-x C-s
でファイルを保存する