gnuplot を使いこなす - 情報処理IIレジュメ(5)

1. はじめに

データ処理を行うには Excel は便利だが、グラフを描くために色々とマウスで作業が必要であり面倒である。マウスで設定作業をするのは、初心者が手探りでグラフを作成できるという意味ではいいのだが、慣れても作業効率が上がらないのが厳しい。すでに第二学年の情報処理で使ってきた gnuplot について、もう少し効率的な使い方を解説する。

(6/14追記: Windows の PDF リーダとして SumatraPDF を使うことで、余計なプロセス停止処理が必要なくなったので、記事を修正した)。

2. gnuplot を使ってみる

自分のマシンの画面が異なると混乱するという意見があったので、macOS 版、Windows 版を併記して表示することにする。以下、左側が macOS、右側が Windows である。macOS はデフォルトで qt ターミナル、Windows は wxt ターミナルである。Windows も qt ターミナルを利用できるのだが、複雑なグラフに難があるとのこと(macOS や Linux は qt で問題なし)。

2.1 起動

macOS はターミナルで gnuplotとタイプする。Windows 版は GUI アプリとなっている。特にメニューなどを使わない場合には、PowerShell から gnuplot とタイプすることで macOS と同様に CUI 版の gnuplot が立ち上がる。今後、2年生の時のように、この画面に直接入力することは、あまりないので GUI のメリットはあまりない。

f:id:hkob:20200521214231p:plainf:id:hkob:20200521214250p:plain
起動画面

2.2 正弦波を書いてみる

先ほどの画面に plot sin(x) とタイプしてみる。-10\leq x\leq 10までのグラフが描画される。

f:id:hkob:20200521214957p:plainf:id:hkob:20200521214736p:plain
sin(x)のグラフ

ここで、1[Hz]の正弦波を書いてみる。plot sin(2*pi*x)とすると画面に少し変な波形が表示される。

f:id:hkob:20200521215259p:plainf:id:hkob:20200521215240p:plain
1[Hz]の正弦波(不具合あり)

理由はshow samplesとすると判明する。グラフの点数が100点と少ないためである(以下、gnuplot>のプロンプト部分は省略する)。

show samples

    sampling rate is 100, 100

そこで、samples の値をもう少し増やして、再描画してみる。

set samples 512
replot

f:id:hkob:20200521215809p:plainf:id:hkob:20200521215842p:plain
1[Hz]の正弦波(不具合解消)

ここでx軸の範囲を-1から1までに変更する。plot の後ろに範囲を指定すればよい。

plot [-1:1] sin(2*pi*x)

f:id:hkob:20200521220220p:plainf:id:hkob:20200521220238p:plain
x軸を-1から1までに限定

次に x 軸が書かれていないので、さらにコマンドを追加してみる。

set xzeroaxis
replot

f:id:hkob:20200521220643p:plainf:id:hkob:20200521220704p:plain
x軸の描画

同様に y 軸もコマンドを追加してみる。

set yzeroaxis
replot

f:id:hkob:20200521221015p:plainf:id:hkob:20200521221054p:plain
y軸も追加

あまり使うことはないがグリッドも書いてみる。

set grid
replot

f:id:hkob:20200521221234p:plainf:id:hkob:20200521221248p:plain
グリッドも追加

各軸のラベルも追加する。

set xlabel "Time t[s]"
set ylabel "Voltage v[V]"
replot

f:id:hkob:20200521221431p:plainf:id:hkob:20200521221448p:plain
軸ラベルの追加

2.3 特殊関数を使ってみる

切り捨ての関数 floor(x) を描画する。

plot [-5:5] floor(x)

f:id:hkob:20200521221817p:plainf:id:hkob:20200521221832p:plain
切り捨て関数 floor(x)

gnuplot は自作の関数を作ることができる。ここでは f(x) という関数を作成し、そのグラフを描画する。この f(x) はどんな関数なのかは各自で考えてみて欲しい(グラフの外形から理解できると思うが)。

f(x) = x - floor(x)
plot [-5:5] f(x)

f:id:hkob:20200521222435p:plainf:id:hkob:20200521222452p:plain
自作関数 f(x)

もう一つの自作関数 g(x) を作ってみる。今回の関数は条件判断が含まれている。こちらも何ができているのかは各自で考えて欲しい。また、高さを自動のままにするとグラフの外径が見えにくくなるので、手動で設定している。

g(x) = floor(x) % 2 == 0 ? 1 : 0
plot [-5:5] [-0.5:1.5] g(x)

f:id:hkob:20200521222827p:plainf:id:hkob:20200521222840p:plain
自作関数 g(x)

最後に複数のグラフの描画を実行してみる。今回は三年生で学ぶ三相交流波形を描いてみよう。三相交流は120度ずつずらした三本の制限は交流である。

plot [-1:1] sin(2*pi*x), sin(2*pi*x+2*pi/3), sin(2*pi*x+4*pi/3)

f:id:hkob:20200521223413p:plainf:id:hkob:20200521223437p:plain
三相交流(キーなし)

デフォルトではキーの部分に記載した関数がそのまま表示される。かなり見にくいので、v_a, v_b, v_cのようにタイトルをつける。LaTeX と同じで_を使うことで下付文字を記載できる。

plot [-1:1] sin(2*pi*x) t "v_a", sin(2*pi*x+2*pi/3) t "v_b", sin(2*pi*x+4*pi/3) t "v_c"

f:id:hkob:20200521224116p:plainf:id:hkob:20200521224148p:plain
波形にタイトルを付ける

3. スクリプトを使って自動化する

これまでの作業を毎回打つのは面倒なので、これを一つのスクリプトにしてしまうと次回以降はそれを複製して修正すればよい。ただし、Windows と macOS でやり方が大きく異なるので、個別に説明する。先ほどの3つの正弦波を表示するスクリプトで説明する。

3.1 macOS の場合の自動化

macOS の場合、シェルスクリプト(普段使っているシェルコマンドの流れをまとめて記述したもの)の中に gnuplot の呼び出しまで含める。gnuplot のスクリプトはヒアドキュメントという機能を使って、シェルスクリプト内に記載する。以下、手順を箇条書きで説明する。

  • すでに作成しているフォルダに移動する。フォルダ名は自分のものに読み替えること。ターミナル(iTerm2など) を開いて以下のコマンドを実行していく。
cd ~/Documents/gnuplotTest
  • 空のシェルスクリプト threeSins.sh を作り、スクリプト実行権限を付ける。
touch threeSins.sh
chmod +x threeSins.sh
  • このファイルをエディタで編集する。Visual Studio Code であれば、以下のコマンドを実行すればよい(他のエディタの場合には、自分で開くこと)。
code threeSins.sh
  • このスクリプトを watch して自動実行するように chokidar を設定する。ファイル名は最初の数文字を書けばあとはタブキー で補完できる。
chokidar threeSins.sh -c ./threeSins.sh
Watching "threeSins.sh" ..
  • これでターミナルの作業は終了である。Visual Studio Code で以下のスクリプトを記載する。ここで、スクリプトを簡単に説明する。
    • FNAME には $0 で示されるスクリプト自身のファイル名から「.sh」を取り除いた文字列が入る。
    • PDF はこの名前に .pdf をつけた名前が入る。今回の場合は、threeSins.pdf という名前になる。
    • gnuplot の後ろに書かれた <<EOF はヒアドキュメントと呼ばれる機能である。次の行から EOF までの行が gnuplot への入力となる。
    • gnuplot 内では、PDF ターミナルを設定し、そのファイル名を先ほど設定した $PDF 変数に設定される。ここでは先ほど描いた3本の sin(x) が描画される。
    • gnuplot の描画が終わると、macOS の open コマンドで作成された pdf ファイルが表示される。
#!/bin/sh

FNAME=${0%.sh}
PDF=${FNAME}.pdf

gnuplot <<EOF
set term pdf color font 'Helvetica,14'
set output '$PDF'
set samples 500
set xzeroaxis
set yzeroaxis
set grid
set xlabel 'Time t[s]'
set ylabel 'Voltage v[V]'
plot [-1:1] sin(2*pi*x) t 'v_a', sin(2*pi*x+2*pi/3) t 'v_b', sin(2*pi*x+4*pi/3) t 'v_c'
quit
EOF
open $PDF
  • 上記のファイルを保存した瞬間に chokidar がファイル更新を認識し、自動的にグラフが出力される。
    f:id:hkob:20200522094830p:plain
    自動出力されたグラフ
  • 必要に応じてファイルを書き換えればグラフが更新されることを確認して欲しい。
  • また別のグラフを書きたければ、このファイルを別名で保存し、gnuplot の中身だけを書き換えればよい。先ほど説明したようにファイル名はシェルスクリプト自体の名前で自動設定されるので、gnuplot 以外の部分は全くいじる必要はない。

3.2 Windows の場合の自動化

(6/14 追記: Windows の Adobe Reader は PDF ファイルを開いている時に、そのファイルを別のプログラムで変更することができなかった。このため、当初の記事では Adobe Reader を終了させる処理を追加していた。その後、同僚から Sumatra PDF を使うと PDF ファイルを外部から変更可能であることを教えてもらった。このため、以下の記事の一部を修正している。)

Windows の場合にはヒアドキュメントの仕組みが使いにくい。そのため、gnuplot のスクリプトの中から、外部コマンドを実行することにする。

  • すでに作成しているフォルダに移動する。フォルダ名は自分のものに読み替えること。PowerShell を開いて以下のコマンドを実行していく。
cd $HOME\Documents\gnuplotTest
  • 空の gnuplot スクリプト threeSins.gp を作る。
New-Item -Type File threeSins.gp
  • このファイルをエディタで編集する。Visual Studio Code であれば、以下のコマンドを実行すればよい(他のエディタの場合には、自分で開くこと)。
code threeSins.gp
  • このスクリプトを watch して自動実行するように chokidar を設定する。二箇所ファイル名を書く場所があるが最初の数文字を入れれば、あとはタブキー で補完できる。ここで、-c のオプションであるコマンドを""で括ることを忘れないこと。
chokidar .\threeSins.gp -c "gnuplot .\threeSins.gp"
  • これでターミナルの作業は終了である。Visual Studio Code で以下のスクリプトを記載する。ここで、スクリプトを簡単に説明する。
    • name には PDF のファイル名を記載する。
    • gnuplot が PDF ファイルを作成しようとするのだが、Windows の場合、すでに Adobe Reader でその PDF ファイルを開いていると PDF を更新することができない。今回は苦肉の策で、Adobe Reader のプロセスを殺すことにした。もし、Adobe Reader 以外のアプリを使っている場合には、exe ファイル名を修正すること。
    • ただし、Adobe Reader はすぐに終了しないので、次の timeout コマンドで 1 秒待つようにしている
    • 事前準備では漢字コードを WIndows 標準の Shift JIS にするようにしたが、エディタでファイルを開くたびにエンコードを変更するのは面倒なので、gnuplot を UTF-8 で動作するように変更した。「set encoding utf8」はそのコマンドである。これで何も気にせずに日本語などを書いてよい。
    • あとは gnuplot のコードとなる。gnuplot 内では、PDF ターミナルを設定し、そのファイル名を先ほど設定した $PDF 変数に設定される。ここでは先ほど描いた3本の sin(x) が描画される。
    • gnuplot の描画が終わると、set output で書き込みを中止し、system コマンドで pdf を実行する。Windows の場合にはファイル名に関連したアプリ(Adobe Reader)が開く。
set encoding utf8
# 最初に文字コードを変更しておかないといけなかった。

# ここの名前は自分で設定する
name = "threeSins.pdf"

# PDF reader として Adobe Reader を使う場合にはコメントを外すこと。SumatraPDF を使う場合は必要なし
# system("taskkill /im AcroRd32.exe")
# system("timeout 1")

# ここからは固定
set term pdf color font 'Arial,10'
set output name

# ここからは自分で変更する部分
set samples 500
set xzeroaxis
set yzeroaxis 
set grid
set xlabel 'Time t[s]'
set ylabel 'Voltage v[V]'
plot [-1:1] sin(2*pi*x) t 'v_a', sin(2*pi*x+2*pi/3) t 'v_b', sin(2*pi*x+4*pi/3) t 'v_c'

# ここから下も固定部分
set output
system(name) 
quit

gnuplot でスクリプトにエラーがある場合は chokidar の画面内で確認することができる。

4. 線種・点種の確認

先ほどの chokidar はどちらの環境でも ctrl-c で止めることができる。次に線種・点種の確認をする画面を表示する。macOS の場合は、ターミナルで threeSins.shをコピーして test.sh を作成し編集する。

cp threeSins.sh test.sh
code test.sh

Windows の場合には、PowerShell で threeSins.gp をコピーして、test.gp を作成し編集するる。

copy threeSins.gp test.gp
code test.gp

macOS の場合には、以下のように修正する(中身をtest に書き換えるだけである)。

#!/bin/sh

FNAME=${0%.sh}
PDF=${FNAME}.pdf

gnuplot <<EOF
set term pdf color font 'Helvetica,14'
set output '$PDF'
test
quit
EOF
open $PDF

Windows の場合にも同様に修正をする。こちらは一番上の name の書き換えを忘れないこと。

name = "threeSins.pdf"
system("taskkill /im AcroRd32.exe")
system("timeout 1")
set encoding utf8
set term pdf color font 'Arial,10'
set output name
test
set output
system(name) 
quit

それぞれの環境で作成された PDF を示す。これを基に今回の課題をして欲しい。

f:id:hkob:20200522141104p:plainf:id:hkob:20200522141123p:plain
test の結果

5. 課題

5.1 課題1: 線種・点種を変更したグラフ

test.pdf の出力を参考に先ほどのグラフの線種・点種などを変更したグラフを作成し提出する。オプションについて(詳しくは help plot の後に style で確認できる)は w styleの形で書く。ここで w は with の省略形である。また、線の種類や点の種類も同様に記述する。以下のものも、区別できれば頭文字だけで Okである。Windows の場合には、PDF が出力できなかった場合には、PowerShell で gnuplot theeSins.gp としてエラーを確認して欲しい。

  • w l: 線で記述
  • w p: 点で記述
  • w lp: 線と点を両方記述
  • lt 数字: (線種の指定)
  • lw 数字: (線の太さの指定)
  • lc 数字: (線の色の指定)
  • pt 数字: (点種の指定)
  • ps 数字: (点のサイズの指定)

提出するもの * gp (Windows) または sh (macOS) * 作成した pdf ファイル

5.2 課題2: 実験データの出力

実験レポートのスタイルファイル内に、実際のデータを使った実験データの出力のやり方が書いてある。Windows、macOS のそれぞれにおいて、gp または sh を作成し、近似曲線まで含めたグラフを作成する

提出するもの * gp (Windows) または sh (macOS) * 作成した pdf ファイル

hkob.hatenablog.com