Chart::Gnuplotでグラフを生成してみよう
本カレンダーの一エントリを担当させていただくにあたり,あわててgitとnimの勉強を始めたばかりの赤フレームなメガネの女性に惹かれるかもしれないissmと申します.他のエントリの方々と比べるとgeek度は皆無だったりしますが,この11日,おつきあいいだたければ幸いです.
目次
- はじめに
- Chart::Gnuplotの概要
- 準備
- 基本
- 実践
- おわりに
はじめに
Perlでグラフを生成するためのモジュールとしては,グラフィックライブラリGDを利用したGD::Graphとか,GoogleChart APIを利用したGoogle::Chartとかが挙げられますが,最近,ふとしたきっかけで,Chart::Gnuplotなるモジュールの存在を知り,実際に使ってみたところ,なかなかいい感じでした.
今回は,そのChart::Gnuplotについて簡単に紹介してみます.
Chart::Gnuplotの概要
グラフ描画系のツールのひとつにgnuplotというものがあります.
スクリーンショットを2点.
- http://farm3.static.flickr.com/2663/4166426208_a8aa809708_o.png
- http://farm3.static.flickr.com/2646/4165669881_f18a216d77_o.png
私の場合,大学在学時のレポートとか卒業研究とかが触れるきっかけでした.TeXで扱うためにEPS形式で出力したものがIllustratorでイジれるとを知って,何やら遊んでいた記憶くらいかありませんが...そんなことはどうでもいいですね><
さて,このgnuplot,数式による描画もデータファイル読み込みによる描画もできたり,ラベルとか目盛りとかをはじめ,グラフ描画に関する様々な設定を細かく行えたりと,便利で高機能です.
そんなgnuplotをPerlから操作するためのインタフェイスを提供してくれるのが,このChart::Gnuplotです.
出力フォーマット
Chart::Gnuplotは,描画したグラフの出力フォーマットとして,次のものをサポートしています.(出力先の拡張子によって自動で切り替えてくれるみたいですね.)
The supported image formats are:
bmp : Microsoft Windows bitmap epdf : Encapsulated Portable Document Format epi : Encapsulated PostScript Interchange format eps : Encapsulated PostScript gif : Graphics Interchange Format jpg : Joint Photographic Experts Group JFIF format pdf : Portable Document Format png : Portable Network Graphics ppm : Portable Pixmap Format ps : PostScript file psd : Adobe Photoshop bitmap file xpm : X Windows system pixmapIf the filename has no extension, postscipt will be used.
cite: http://search.cpan.org/~kwmak/Chart-Gnuplot/lib/Chart/Gnuplot.pm#output
これだけサポートしてくれていれば,まず困らないのではないでしょうか.
グラフ描画
gnuplotでは,2次元だけでなく,3次元の描画も行えます.もちろん,Chart::Gnuplotからでも可能です.
しかし,ここでは簡単に2次元描画にしぼって行きたいと思います.(私が試したことがないので.)
準備
前置きが長くなりましたが,まずは準備から.
In order to use this module, gnuplot need to be installed. If image format other than PS, PDF and EPS is required to generate, the convert program of ImageMagick is also needed.
cite: http://search.cpan.org/~kwmak/Chart-Gnuplot/lib/Chart/Gnuplot.pm#DESCRIPTION
ということなので,gnuplotとかImageMagickとかをインストールしておきます.(ImageMagickは,PostScript・PDF・EPS形式以外のときに必要になります.入れておいて損はないかと思います.)
% sudo port install gnuplot % sudo port install ImageMagick +perl % sudo cpan -i Chart::Gnuplot
※ プラットフォームによって適宜置き換えてください.
基本
基本的な使い方は,だいたい次のような流れになります.
- 描画用データの準備
- gnuplotオブジェクトの生成・設定
- データセットオブジェクトの生成・設定
- 描画・出力
コードにすると,こんな感じです.
use Chart::Gnuplot; # データの準備 my $xdata = [...]; my $ydata = [...]; # gnuplotオブジェクトの生成・設定 my $chart = Chart::Gnuplot->new( output => $filename, %opts_chart, ); # データセットオブジェクトの生成・設定 my $dataset = Chart::Gnuplot::DataSet->new( xdata => $xdata, # arrayref ydata => $ydata, # arrayref %opts_dataset, ); # 描画・出力 $chart->plot2d($dataset);
ちなみに,複数のデータセットを一度に描画することもできます.
my $dataset2 = Chart::Gnuplot::DataSet->new(...); $chart->plot2d($dataset, $dataset2);
実践
もうちょっと実践的にやってみましょう.
データファイル
次のデータは,とあるサーバの負荷平均(ロードアベレージ)を,1日間,約10秒間隔で記録したものの一部です.(uptimeコマンドの出力を利用しています.)
1259593206,0.27,0.18,0.26 1259593216,0.31,0.19,0.27 1259593226,0.26,0.18,0.26 1259593236,0.22,0.17,0.26 1259593246,0.18,0.17,0.26 1259593256,0.16,0.16,0.25 1259593266,0.21,0.17,0.26 1259593276,0.18,0.17,0.25 1259593286,0.15,0.16,0.25 1259593296,0.13,0.15,0.25 ... 1259679501,0.69,0.85,0.95 1259679511,1.20,0.96,0.98 1259679521,1.16,0.96,0.98 1259679531,1.38,1.01,0.99 1259679541,1.24,0.99,0.99 1259679551,1.12,0.97,0.98 1259679561,0.95,0.94,0.97 1259679571,0.80,0.91,0.96 1259679581,1.14,0.98,0.98 1259679591,0.97,0.95,0.97
このファイル名を,uptime.datとでもしておきます.
データの読み込み
データファイルにおける,コンマで区切った1列目(時刻)の系列を横軸,2列目(1分間の負荷平均値)の系列を縦軸としたグラフを生成することを考えてみます.
ということで,必要な部分を読み込みます.
my $t = []; # 1列目のデータ系列が入る my $y = []; # 2列目のデータ系列が入る open my $fh, '<', 'uptime.dat' or die $!; while (my $row = <$fh>) { #chomp $row; my ($time, $load) = split /,/, $row; # 時刻データを,00:00:00からの秒数に置き換える my ($ss, $mm, $hh) = (localtime $time)[0..2]; $time = ($hh*60*60 + $mm*60 + $ss); $time /= 60*60; # 1時間を0〜1の範囲に圧縮する push @$t, $time; push @$y, $load; } close $fh;
gnuplotオブジェクトの準備
次にgnuplotオブジェクトを生成します.
#use Chart::Gnuplot; しているものとします my $chart = Chart::Gnuplot->new( output => 'uptime.png', imagesize => '1.5, 1.0', title => '2009-12-01', xrange => [0, 24], yrange => [0, 3], xlabel => 'time', ylabel => 'load', grid => { width => 2, color => '#666666', }, xtics => { along => 1, }, ytics => { along => .5, labelfmt => '%.1f', }, orient => 'landscape', );
ここでのオプションの概要は次のような感じです.
- output
- 出力先
- imagesize
- 出力の相対的なサイズ
- xrange
- 横軸の値の範囲
- yrange
- 縦軸の値の範囲
- xlabel
- 横軸につけるラベル
- ylabel
- 縦軸につけるラベル
- grid
- 補助線の種類とか色とか
- xtics
- 横軸の刻み
- ytics
- 縦軸の刻み
- orient
- 用紙(?)の方向
gnuplotを使われたことのある方にとっては馴染みのある単語が並んでいますね.
詳細はCPANの同モジュールのページをご覧ください
データセットオブジェクトの準備
先に準備したデータを基に,データセットオブジェクトを生成します.
my $dataset = Chart::Gnuplot::DataSet->new( xdata => $t, ydata => $y, style => 'impulses', color => '#ff0000', );
ここでのオプションの概要は次のような感じです.
- xdata
- 横軸のデータ
- ydata
- 縦軸のデータ
- style
- 描画の種類
- color
- 描画の色
描画の種類によって指定する項目が異なったりします.詳細は次をご覧ください.
描画・出力
あとは,次の1行で出力するだけです.
$chart->plot2d($dataset);
できあがり
すると,次のようなPNG画像ができあがります.
おわりに
以上,Chart::Gnuplotの概要と,同モジュールを使ってグラフを生成する過程をざっと紹介してみました.
それでは,楽しいグラフ描画ライフをおすごしください.
さーて,明日のカジュアルさんは?
冒頭で少し言及したGoogle::Chartモジュールの作者でもあるlestrratさんです.お楽しみに!