09. gnuplot グラフ描画の基本

graph Photo by Luke Chesser on Unsplash

この回で身につける考え方

この回では,数値や関数をグラフとして可視化するための道具として gnuplot を学ぶ. この回で最も大事なのは,個々のコマンドを暗記することではなく,

手で1枚描いて確認し,その命令をファイルに保存して,再現可能な作図へ進む

という考え方である. Unix/Linux の授業という文脈では,gnuplot は単なるグラフ作成ソフトではなく, シェルスクリプトや make から呼び出して使える「作図用コマンド」としても重要である.

gnuplot overview

具体的には,次のことを扱う.

  • gnuplot を起動し,終了し,ヘルプを見る.
  • plot で1変数関数を描く.
  • splot で2変数関数を3次元的に描く.
  • 数値データファイルをグラフにする.
  • グラフを png, pdf, svg などのファイルに保存する.
  • gnuplot の命令を .gpl ファイルに書き,非対話的に実行する.
  • 連番画像を作り,ffmpeg と組み合わせて動画を作る.

interactive and script modes

  数学や数値計算のレポートでは,正しい計算結果を得るだけでなく,その結果を他人が理解しやすい図にすることも大切である. 可視化は「おまけ」ではなく,結果を確認し,説明し,伝えるための基本技能だと思っておこう.

gnuplot とは

gnuplot とは,対話的にも非対話的にも使える,CUI を通じた由緒正しいグラフ作成ツールである. 関数のグラフも,データファイルのグラフも描ける. また,GUI アプリケーションとして画面上で使うこともできるし,コマンドラインから機械的に実行することもできる.

特徴をまとめると,次のようになる.

  • まずはコマンドを1行ずつ入力して反応を見る,対話的な使い方ができる.
  • 同じコマンド列をファイルに書いておけば,スクリプトとして非対話的に実行できる.
  • 関数のグラフと,データファイルのグラフの両方を扱える.
  • png, svg, pdf, eps など,多くの画像形式に出力できる.
  • TeX, Web, シェルスクリプト,make などと相性が良い.

なにが出来るのか

まずは gnuplot 本家 web の右下にある Development version の demo gallery を眺め,どのような図が作れるのか見ておこう. 文字を細かく読む必要はない. 図をざっと見るだけでも,gnuplot の守備範囲がかなり広いことが分かるはずである.

起動,終了,ヘルプ

起動

端末から gnuplot を起動するには,コマンドとして

1gnuplot

と入力すればよい. 起動すると,通常のシェルのプロンプトではなく,gnuplot のプロンプトが表示される. この状態で入力する命令は,シェルコマンドではなく gnuplot の命令 である.

Windows 用にインストールされた gnuplot は,スタートメニューから起動することもできる. ただし,この授業では後でコマンドとして呼び出すので,端末から起動する方法も知っておこう.

終了

gnuplot を終了するには,gnuplot の命令として

1exit

または

1quit

と入力する. GUI ウィンドウとして起動している場合は,ウィンドウを閉じてもよい.

ヘルプ

gnuplot のヘルプを見るには,gnuplot の中で

1help

または

1?

と入力する. 例えば plot について調べたければ,

1help plot

のようにする. ヘルプは多層構造で少し読みにくいが,実際に困った時には十分役に立つ.

  今,自分がシェルに命令しているのか,gnuplot に命令しているのかを常に意識しよう. gnuplot と入力するのはシェルである. plot sin(x) と入力するのは gnuplot の中である.

ごく簡単な例

まずは関数 $\displaystyle \frac{\sin x}{x}$ のグラフを描いてみよう.

  実習

  1. gnuplot を起動する.
  2. gnuplot の中で次を入力する.
1set samples 300
2plot [-30:30] sin(x)/x

set samples 300 は,関数を描くために使う点の数を増やす命令である. plot [-30:30] sin(x)/x は,$-30 \le x \le 30$ の範囲で $\sin(x)/x$ を描け,という命令である.

clean sin x over x

上の図のようなグラフが表示されれば成功である.

  gnuplot では,数学でよく書く $x^2$ は x**2 と書く. また,掛け算の * は省略できない. 例えば $2x+1$ は 2*x+1 と書く.

関数を描く: plot

plot コマンドを使うと,1変数関数のグラフを描くことができる. 組み込みの初等関数だけでなく,自分で定義した関数も使える.

plot function flow

例えば,gnuplot の中で

1f(x) = x**2 + 2*x + 1
2plot f(x)

と入力すると,$f(x)=x^2+2x+1$ のグラフを描ける.

  gnuplot では,直交座標軸を表す独立変数は,1つ目が x,2つ目が y,3つ目が z である. 通常の1変数関数のグラフでは x を使う.

plot でよく使う指定

最初に覚えるべき指定は多くない. 次の図の項目を,必要になった時に思い出せれば十分である.

plot options

例1: 描画範囲を指定する

1plot [-3:3] [-1.2:1.2] sin(x)

1つ目の [-3:3] は $x$ 軸の範囲,2つ目の [-1.2:1.2] は $y$ 軸の範囲を表す. また,あらかじめ

1set xrange [-3:3]
2set yrange [-1.2:1.2]
3plot sin(x)

としてもよい.

例2: 線ではなく点で描く

1plot sin(x) with points

with pointsw p と省略できる. 他にも,よく使うものとして

  • with lines または w l
  • with linespoints または w lp
  • with impulses
  • with boxes

などがある.

例3: 2つ以上の関数を同時に描く

1plot sin(x), cos(x)

カンマで区切るだけで,複数の関数を同じ図に描ける. 凡例の名前を付けたい場合は次のようにする.

1plot sin(x) title "sin", cos(x) title "cos"

例4: 場合分けされた関数を描く

gnuplot には三項演算子 ? : がある. これを使うと,場合分けされた関数も描ける.

1f(x) = x>0 ? sin(x) : x**2
2plot [-2:2] f(x)

三項演算子は重ねることもできる.

1f(x) = x>0 ? sin(x) : (x>-1 ? x**2 : x+2)
2plot [-2:2] f(x)

この例で得られるグラフは次のようになる.

ternary operator example

  実習

次の関数を gnuplot で描いてみよう. 描画範囲や描き方を自分で調整すること.

  1. sin(x)cos(x)
  2. exp(-x*x)
  3. x**3 - 3*x
  4. x>0 ? x : -x

3次元グラフを描く: splot

plot が1変数関数を2次元平面に描く命令であるのに対し,splot は主に2変数関数を3次元的に描く命令である.

splot concept

例えば,gnuplot の中で

1splot x**2 + y**2

としてみよう. 出てきた3次元グラフをマウスで掴んで動かすと,様々な視点から曲面を見ることができるはずである.

splot paraboloid

splot でよく使う指定

範囲を指定する

1splot [-3:3] [-3:3] [0:20] x**2 + y**2

この場合,1つ目が $x$ の範囲,2つ目が $y$ の範囲,3つ目が $z$ の範囲である.

格子点を増やして滑らかにする

1set isosamples 80
2splot x**2 + y**2

plot の時の set samples に対応するものが,3次元描画での set isosamples である. 大きくしすぎると描画が重くなるので注意しよう.

視点を変える

1set view 45, 60, 1.0
2splot x**2 + y**2

set view を使うと視点を数値で指定できる. ただし,最初のうちはマウスで動かしてみるだけで十分である.

等高線や色付けを使う

1set contour
2set hidden3d
3splot x**2 + y**2

または

1set pm3d
2splot x**2 + y**2

のようにすると,等高線や色付きの曲面を表示できる.

  実習

次の関数を splot で描いてみよう. 可能なら視点を変えたり,set pm3d も試してみよう.

  1. x**2 + y**2
  2. sin(x)*cos(y)
  3. exp(-(x**2+y**2))
  4. sin(sqrt(x**2+y**2))

データをグラフにする

gnuplot は関数だけでなく,データファイルもグラフにできる. 数値計算や実験の結果を描く時には,こちらの使い方が本命である.

data plot flow

準備: データファイルを作る

まず,作業用ディレクトリを作って移動しておこう. 例えば,シェルで次のようにする.

1cd ~
2mkdir -p work/gnuplot09
3cd work/gnuplot09

次に,dummy.dat というファイルを作り,次の内容を保存する.

 10.0   0.000
 20.2   0.199
 30.4   0.389
 40.6   0.565
 50.8   0.717
 61.0   0.841
 71.2   0.932
 81.4   0.985
 91.6   1.000
101.8   0.974
112.0   0.909
122.2   0.808
132.4   0.675
142.6   0.516
152.8   0.335
163.0   0.141
173.2  -0.058
183.4  -0.256
193.6  -0.443
203.8  -0.612
214.0  -0.757
224.2  -0.872
234.4  -0.952
244.6  -0.994
254.8  -0.996
265.0  -0.959
275.2  -0.883
285.4  -0.773
295.6  -0.631
305.8  -0.465
316.0  -0.279
326.2  -0.083
336.4   0.117
346.6   0.312
356.8   0.494
367.0   0.657
377.2   0.794
387.4   0.899
397.6   0.968
407.8   0.999
418.0   0.989

このファイルは,1列目が $x$ 座標,2列目が $y$ 座標である.

データを点で描く

gnuplot を起動し,次を入力する.

1plot "dummy.dat"

多くの点が表示されるはずである. 明示的に1列目を横軸,2列目を縦軸にするときは,次のように書く.

1plot "dummy.dat" using 1:2

線で結ぶ,点も打つ

点を線で結びたければ,次のようにする.

1plot "dummy.dat" using 1:2 with lines

点も表示したければ,次のようにする.

1plot "dummy.dat" using 1:2 with linespoints

省略形を使えば,次のようにも書ける.

1plot "dummy.dat" u 1:2 w lp

この結果は,例えば次のようなグラフになる.

dummy data linespoints

データファイルの基本ルール

最初は次のルールだけ分かっていればよい.

  • 1行が1つのデータ点に対応する.
  • 空白またはタブで区切られたものが「列」になる.
  • using 1:2 は「1列目を横軸,2列目を縦軸に使う」という意味である.
  • # で始まる行はコメントとして扱われる.
  • 列が多い場合は,using 1:3using 2:4 のように選べる.

  実習

自分で小さなデータファイルを作り,gnuplot でグラフにしてみよう. 例えば,次のようなデータが考えられる.

  • $x$ と $x^2$ の対応表
  • $x$ と $\sin x$ の対応表
  • 日付と気温のような簡単な時系列データ

グラフをファイルに保存する

グラフをレポートや web ページで使うには,画面に表示するだけでなく,画像ファイルとして保存する必要がある. 保存方法は大きく分けて2つある.

  1. 表示ウィンドウの save/export 機能で保存する.
  2. gnuplot の命令で出力形式とファイル名を指定して保存する.

Windows の新しめの gnuplot では,wxtqt terminal を使うと,表示しているグラフを GUI から保存できることが多い.

gnuplot 6.0.4

Windows 用 gnuplot 6.0.4 版で set term wxt 設定にしてグラフを描いた様子.

windows terminal choice

ただし,スクリプト化や自動化を考えるならば,コマンドで保存する方法が重要である. 基本手順は次の通りである.

terminal output flow

例えば,png ファイルとして保存したい場合は,gnuplot の中で次のようにする.

1set terminal pngcairo size 1280,960
2set output "graph.png"
3plot sin(x)
4unset output

pdf ファイルとして保存したい場合は,例えば次のようにする.

1set terminal pdfcairo
2set output "graph.pdf"
3plot sin(x)
4unset output

svg ファイルとして保存したい場合は,例えば次のようにする.

1set terminal svg
2set output "graph.svg"
3plot sin(x)
4unset output

file format choice

  set output で指定したファイルへの出力が終わったら,unset output で閉じておく,と覚えておこう. これを忘れると,ファイルが未完成になったり,次の描画結果が同じファイルに書き込まれたりして混乱しやすい.

  実習

適当なグラフを作り,png, pdf, svg のいずれかで保存してみよう. 保存したファイルをエクスプローラーやブラウザで開き,実際に表示されることを確認しよう.

非対話的に使う: gnuplot スクリプト

ここまでは,gnuplot の中で1行ずつ命令を入力してきた. しかし,同じグラフを何度も作るなら,命令をファイルに保存しておく方がよい.

script to images

gnuplot の命令を書いたファイルには,例えば .gpl という拡張子を付けることが多い. ここでは sin2png.gpl というファイルを作り,次の内容を書き込もう.

 1set title "sin(100*x)+sin((100+dk)*x)"
 2set samples 5000
 3set xrange [-10:10]
 4set xlabel "x"
 5set terminal pngcairo size 1280,960
 6
 7base = 100
 8
 9do for [num = 0:100] {
10  dk = num / 100.0
11  outf = sprintf("%04.0f.png", num)
12  leg = sprintf("dk = %02.2f", dk)
13
14  set output outf
15  plot sin(base*x)+sin((base+dk)*x) title leg
16}
17
18unset output

このファイルがあるディレクトリで,シェルから

1gnuplot -d sin2png.gpl

と実行する. 問題がなければ,0000.png から 0100.png までの101個の画像ファイルができる.

  ここで -d は,gnuplot の個人設定ファイルによる影響を受けにくくするためのオプションである. 通常は付けなくても動くことが多いが,授業ではトラブルを減らすために付けている.

短い命令を直接渡す

短い命令なら,.gpl ファイルを作らず,シェルから直接与えることもできる.

1gnuplot -e "set term dumb; plot sin(x)"

set term dumb は,普通の端末画面に文字だけでグラフを描く指定である. SSH 先や,画像表示が使えない環境で概形を確認したい時に便利である.

  実習

sin2png.gpl の中の関数や範囲を少し変え,連番画像をもう一度作ってみよう. 例えば sin(base*x) の代わりに cos(base*x) を使うなど,簡単な変更でよい.

連番画像から動画を作る: Frame Sequence

連番画像を作れるようになると,それらを結合して動画にできる. 数値計算結果を時刻ごとに描く場合などに,この方法は非常によく使われる.

frame sequence flow

阪大教育用計算機の Windows では,Windows Terminal などから ffmpeg コマンドが使える場合がある. また,各自 PC に ffmpeg をインストールしてもよい. Ubuntu なら例えば

1sudo apt install ffmpeg

でインストールできる.

先ほど作った 0000.png から 0100.png までの画像があるディレクトリで,次を実行してみよう.

1ffmpeg -r 8 -i "./%04d.png" -vcodec h264 -pix_fmt yuv420p ./tone.mp4

tone.mp4 という動画ファイルが作られる. ブラウザや動画プレイヤーで開いて確認しよう.

もし古い形式の動画を作りたい場合は,例えば次のようにもできる.

1ffmpeg -i "./%04d.png" ./tone.mpg

  tips: 上の実行例は,データを動画にする可視化の初歩かつ基本的な手法

「連番画像を生成して,結合して動画を作る」
   Frame Sequence

の典型的な例として覚えておこう.


  実習

  1. sin2png.gpl によって連番画像を作る.
  2. ffmpeg で動画ファイルにする.
  3. できた動画を再生して確認する.

ここまでの整理

この回の流れは,次のようにまとめられる.

  1. まず plot で関数を描く.
  2. 次に splot で3次元グラフを描く.
  3. データファイルを plot "file.dat" using 1:2 で描く.
  4. set terminalset output でファイルに保存する.
  5. gnuplot の命令を .gpl ファイルに書いて非対話的に実行する.
  6. 連番画像を ffmpeg で動画にする.

report ideas

この授業の文脈では,gnuplot は「グラフ作成ソフト」であると同時に,「シェルや make から呼べる可視化用コマンド」でもある. 前回までに扱ったシェルスクリプトや Makefile と組み合わせると,数値計算から図の生成までをかなり自動化できる.

発展・補足編

以下は,基本編の内容に対する発展・補足である. 学習初期には読み飛ばして構わない. 授業時にも,時間がなければ扱わない予定である.

複素数を含む関数を描く

あまり知られていないが,gnuplot 自身も複素数を扱える. real で実部,imag で虚部を取り出せる. 例えば,log(x) で $x$ が負の時にどうなっているかを見たいなら,次のようにする.

1plot real(log(x)), imag(log(x))

得られるグラフは以下のようになる.

complex example 01

引数も複素数にしたい場合は,例えば

1i = {0,1}

として,i を虚数単位として使うとよい. この状態で次のようにすると,複素対数関数の虚部の原点付近の様子を見ることができる.

1set isosamples 200
2splot imag(log(x+i*y))

complex example 02

画像形式の指定についてもう少し詳しく

保存する画像形式は,set terminal で指定する. 例えば次のようにする.

画像形式 指定例
png set terminal pngcairo size 1280,960
pdf set terminal pdfcairo
svg set terminal svg
eps set terminal postscript eps
文字端末 set terminal dumb

古い環境では,pngcairopdfcairo が使えないことがある. その場合は,help terminal で使える terminal を確認しよう.

set outputunset output

ファイル名は set output で指定する.

1set output "graph.png"

出力が終わったら,次のようにして閉じる.

1unset output

unset terminal で terminal の指定を戻すこともできるが,通常の作業では unset output を忘れないことの方が重要である.

参考資料

名称(リンク) 説明
gnuplot gnuplot 本家 web.最新版やドキュメントを入手できる.
gnuplot のページ(Takeno Lab) gnuplot マニュアルの日本語訳などがある.大変ありがたい資料である.
GNUPLOT - not so Frequently Asked Questions - 古い資料だが,gnuplot の使い方に関する howto が多い.見えない場合は Wayback Machine を使うとよい.

それぞれの学習環境での状況

環境 状況
阪大情報教育システム Windows 11 Windows 用 gnuplot がインストール済みであれば,スタートメニューや端末から利用できる.
各自 PC Ubuntu 未インストールなら sudo apt install gnuplot でインストールできることが多い.
各自 PC Windows gnuplot 本家 web から Windows 版を入手できる.
各自 PC macOS Homebrew を使うなら brew install gnuplot でインストールできることが多い.

エディタから gnuplot を使う

Emacs 用には gnuplot packagegnuplot-mode package がある. Emacs から gnuplot を呼び出したり,gnuplot スクリプトを編集しやすくしたりできる.

また,Visual Studio Code にも gnuplot 用の拡張機能や外部ツール連携の方法がある. .gpl ファイルを何度も編集して実行するようになったら,エディタ連携を調べる価値がある.

レポート No.9

  注意

近年はセキュリティ上の懸念から,実行形式のプログラムなどをメールに添付すると,そのメール自体の受信を受信側サーバが拒否することがある. そういうことを避けるため,レポートをファイルで提出するときは,そのような懸念のあるファイル形式を避けるようにしよう.

要するに,レポートは PDF ファイルにして送るのが良い と思っておけばよい.

以下の課題について,自らの将来のスキルアップに繋がるように調査と考察を行い,
     学籍番号-氏名-09.pdf
というファイルとしてレポートを作成し, webフォーム から教官宛に提出しよう.

なお,レポートを $\TeX$ 等で作成したものを印刷した「紙媒体」を教官に直接手渡す形で提出してもよいが,物質によるレポート提出は常に破損や紛失の可能性があるのであまりお勧めはしないぞ.

課題

  1. 他に面白い動画ファイルを,gnuplot と ffmpeg の組み合わせで作ってみて,解説せよ. その際,どのような量を変化させ,それが動画の中でどのように見えるのかを説明すること.

  2. 前回の内容で gnuplot を用いている. その用い方について解説せよ. 特に,どのファイルが入力で,どの命令により,どの画像ファイルが作られているのかを整理するとよい.

  3. 毎日一度ずつ,シェルスクリプトを通じて gnuplot を呼び出してグラフ画像ファイルを作らせておくとよさそうな例を考え,実際に動かしてみよう. 毎日自動で動くようにする段階まではできていなくてよい. ただし,「毎日グラフ化すると何が嬉しいのか」は考察すること.

  4. Emacs 用の gnuplot packagegnuplot-mode package を用いると,Emacs から gnuplot を呼び出したり,gnuplot スクリプトを編集しやすくしたりできる. もしも貴殿が Emacs を使う人ならば,この package のいずれかを試してみよう.

    また,無料のエディタ Visual Studio Code にも gnuplot 用の支援機能がある. VS Code 使いの人は試してみよう.