この文書の URL は http://www.cc.kyoto-su.ac.jp/~mtkg/lecture/comp_A/2012/10.html です。

図をファイルに出力する

絵をファイルに出力するには set terminal コマンドと set output コマンドを使います。

set terminal     画像フォーマット(形式)を設定する
set output       出力する画像ファイルの名前を設定する

多くの画像フォーマットに対応していますがよく使われるのは

などでしょう。 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 の出力先をディスプレイに戻すには terminalwxt を指定します。 (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. 条件分岐 (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 でファイルを作成する手順は次のようになります。

  1. C-x C-f でファイル名を入力する
  2. ファイルを編集する
  3. C-x C-s でファイルを保存する