Linuxターミナル、コマンドtips その5: gnuplotの基本的な使い方と勉強会を開く時に期待してはいけないこと
(2019/06/29追記) 実践的、網羅的かつ簡潔にまとまったドキュメントを見つけたのでメモ(日本語訳)*1。
このtipsはこれからLinuxを使っていく必要がある人、特に端末操作に苦戦している人、もしくは端末操作に対して嫌悪感すら抱いている人に向けて書いたものです.作成の経緯はその1の冒頭および注釈に書きました.
今回は、Linuxターミナル、コマンドtipsと銘打ってますが、言うほど一般的な話題ではないです.gnuplotに興味が無ければ前回のシェルスクリプトの活用例としてどうぞ.
前回の話題
Linuxターミナル、コマンドtips その4: シェルスクリプトのハマリ所とデバッグ手法
今回の話題
gnuplotの基本的な使い方
シンプルなgnuplotから始まり、複雑なグラフを描けるようにしていく
また、使い回せるようにシェルスクリプトとしての工夫を少しだけやる
最低限必要そうな設定だけを行ったgnuplot
最初からヒアドキュメントを使ってシェルスクリプトにしているので、そのまま使用可能
まずは以下のプロットデータをグラフ化してみる
プロットデータを記録しているファイル内で#
で始まる行はコメント扱い
X/Yのデータのデリミタはデフォルトでスペース
#X Y 1 10 2 20 3 30 4 40
上記のプロットデータをsample1.plotというファイル名で用意した上で以下のスクリプトを実行すると、以下のsample1.png
が生成される
#!/bin/bash # ヒアドキュメント(<<- EOFから始まってEOFで終わるコード)を使ってgnuplot用のスクリプトを直接gnuplotに実行してもらう gnuplot <<- EOF #Y軸のグリッド線を入れる set grid y #凡例の位置(center, left, right, outside, top, bottom等) set key center top #xy軸のラベル設定 set xlabel "hoge" set ylabel "fuga" #図のタイトル、論文やスライドのグラフには原則不要、進捗報告用とかに set title "title hogefuga" #png画像を作る場合 set terminal png #出力先のファイル指定(相対パス) set output "./sample1.png" # プロットデータからグラフ生成 # 基本:plot "filename" with 描画スタイル オプション # withの後に続く描画スタイルの指定(必須)でグラフの種類が決まる # with lp(linespoints) # title:凡例名 plot "./sample1.plot" with lp title "foobar" EOF
生成されたsample1.png
もう少し色々やったgnuplot
1つのプロットファイルに複数のデータを書いておき、それらを1つのグラフにまとめて出力できる
例えば, 以下のような形のプロットデータがあるとする
#x y1 y2 y3 20 100 150 700 30 300 150 200 40 900 150 400
上記プロットデータを保存したsample2.plot
というファイルを用意した上で以下のスクリプトを実行すると、sample2.png
というグラフが生成される
ここでは、フォントサイズ、画像サイズ、値の範囲、グラフの点や色のカスタマイズなど、見栄えの問題でやりたいことをひと通りやってみた
#!/bin/bash gnuplot <<- EOF #Y軸のグリッド線を入れる set grid y #凡例の位置(outside)、フォント(Times New Roman,26)、フォントサイズ(26)、凡例の幅調整(spacing) set key right font 'Times New Roman,26' spacing 1.5 # 目盛りのフォントの変更 set tics font "Times New Roman,25" #xy軸のラベル設定、フォント(Times New Roman,26)、フォントサイズ(26)、位置調整(offset) set xlabel "hoge" font 'Times New Roman,26' offset 0.0,-1.0 set ylabel "fuga" font 'Times New Roman,26' offset -1.0,0.0 #図のタイトル set title "title hogefuga2" #xy軸の範囲指定、複数のグラフの比較を行う時は原則範囲を揃える set xrange [20:40] set yrange [10:1000] #png画像を(1024,512)のサイズで出力する set terminal png size 1024,512 #出力先のファイル指定(相対パス) set output "./sample2.png" # withの後に続く描画スタイルの指定(必須)でグラフの種類が決まる # with lp(linespoints) # 描画スタイルに続けて、細かい設定を行う # lt(line_type):グラフのタイプ # lw(line_width):グラフの線の太さ # lc(line_color):グラフの色(lc rgb "red"で色の名前で色指定できる) # pt(point_type):点のタイプ # ps:点のサイズ(point_size) # title:凡例名 # 1つのグラフに複数の結果を載せる場合(1つのプロットファイルに複数のプロットデータが入っている場合) # 改行する時は、必ず'\'が必要なので注意 plot "./sample2.plot" using 1:2 with lp lt 1 lw 2 pt 3 ps 2 lc rgb "green" title "hoge",\ "" using 1:3 with lp lt 2 lw 2 pt 4 ps 2 lc rgb "purple" title "fuga",\ "" using 1:4 with lp lt 3 lw 2 pt 5 ps 2 lc rgb "black" title "foo" EOF
生成されたsample2.png
もう少し使い勝手を考慮したgnuplotスクリプト
プロットデータは、グラフごとにファイルが分かれていても、同様に1つのグラフに同時に描画することができる
sample3-1.plot
20 100 30 300 40 900
sample3-2.plot
20 150 30 150 40 150
sample3-3.plot
20 0.25 30 0.4 40 0.15
例えば、以下のスクリプトのファイル名をsample3.bash
として、bash sample3.bash sample3.png
と実行するとsample3.png
という名前のグラフが生成される
ここでは、出力される画像のファイル名を引数で渡すようにしている
もし、引数を指定しない場合は、
$ bash sample3.bash Usage: sample3.bash [output-filename]
と、Usageが出力されるようにしている
sample3-3.plot
だけ、プロットデータが小さいことに注意
スケールが大きく異なる場合は、以下のようにY軸を2軸にして出力することで対応することができる
#!/bin/bash #引数のチェック if [ $# -ne 1 ]; then echo "Usage: $0 [output-filename]" exit fi gnuplot <<- EOF set grid y #フォントサイズだけ指定したい場合は以下のようにフォント名を省略する set key left font ',26' spacing 1.5 set tics font ",25" set xlabel "hoge" font ',26' set ylabel "fuga" font ',26' set title "title hogefuga2" set xrange [20:40] set yrange [10:1000] #Y軸を2軸にする set y2tics set y2range [0.01:0.5] set terminal png size 1024,512 set output "$1" #y2を使用する場合は'axes x1y2'とする plot "./sample3-1.plot" with lp lt 1 lw 2 pt 3 ps 2 lc rgb "green" title "hoge",\ "./sample3-2.plot" with lp lt 2 lw 2 pt 4 ps 2 lc rgb "purple" title "fuga",\ "./sample3-3.plot" axes x1y2 with lp lt 3 lw 2 pt 5 ps 2 lc rgb "black" title "foo" EOF
生成されたsample3.png
gnuplotの威力と辛み
何と言ってもプロットデータをプレーンテキストとして扱えるのが良い.例えば、自作のプログラムの実行時間を計測してその結果をグラフにまとめたい場合、プログラム自身やプログラムを起動するスクリプトに実行時間を変数と共にファイルに吐き出させるようにしておけば、そのファイルがそのままgnuplotのプロットファイルとなるので、測定からグラフ化までのフローを全て自動化することができる.また、gnuplotはかなり複雑なグラフも描画可能なので、ほとんどの用途に応えることができる.
ただ、本稿では一所懸命スクリプト化を行っているが、個人的にはデータやグラフを載せる先に応じて、必要なグラフの形が頻繁に変わるので、結局基本使い捨てというか、雛形となるヒアドキュメントを基にコピペ量産して似たようなヒアドキュメントの山をメンテナンスし続けるということが多かった.もっと良いやり方があるのかもしれないが...
勉強会を開く時に期待してはいけないこと
ターミナルのショートカットキーから始まってかなり駆け足でシェルスクリプトの活用例まで全5回分をブログに載せました.全て今から約半年前に私が研究室の後輩に向けて書いたものです.研究室ではこの後に、人様のスライドをお借りしてGit入門なんかもやりましたが、全編通して手応えがあるとは言いがたい結果でした.内容はぶっ飛ばしすぎだし、途中ドキュメント作成が滞って1ヶ月以上空いたし、当然と言えば当然ですが、とにかく人の興味を何かに向けるには想像以上の誠実さとエネルギーが必要であることを学びました.社内勉強会の作り方(1)期待してはいけない10のことに書いてある内容の全て、すなわち以下の項目は、実感を持って真であると今なら言えます.
- 頑張って考えた企画であれば人が集まるとか期待しない。
- 勉強会が仕事の役に立つとか期待しない。
- 誰かが助けてくれるとか期待しない。
- 急に何かが変わるとか期待しない。
- 自分に期待しない。
興味を持ってくれて学習が進み始めた時に最も役立つようにリンク多めのドキュメント作成をと思っていましたし、上記ブログを読む前から期待してはいけないと思っていたのですが*3、やる以上それなりの期待を持つのが人だと思います.だからこそ上記の期待しない心構えは精神衛生上、本当に大事だなと感じています.少なくとも勉強会などというものを、半端な覚悟で"やる"などと言うべきではないことはわかりました.折れて辞めようものなら今度は少ないながらも期待していてくれた人を裏切ることにも繋がります.
と言う訳で、世の勉強会を継続して開催している全ての人に尊敬の念を抱かずには居られないわけであります.
*1:毎日それこそ息するように使っているものから、必要な時に覚えてなくて毎回ググっているものまで、ベタだけどまさに当時これが手元にあればなぁという内容で良くできている。このブログを読んでくれるのも嬉しいけど、何ができて何を調べれば良いかをまず知る目的で一回このドキュメントも一通り読んでおくと、"あれどうやるんだっけなー"などとボヤきつつ当てもなくググる時間を減らせるはず。要チェック。
*2:グラフ生成ツールとして世の中的にどの程度普及しているのか、一般的なのかはわかりません.個人的には便利だけど学習コスト高杉という感想です.他に学習コストが低い良い物があればそちらでも良いと思います.
*3:だからこそ完全自由参加の勉強会というなるべく押し付けがましくない形を取りました