師匠の散歩

Perlで遊ぼう

GDモジュール

参考資料
GD::Graph日本語訳
GD::Text日本語訳
http://www.gadgety.net/shin/tips/unix/perl-gd.html
参考サイト

GDモジュールでグラフを作成する

もともとPerlで一番やりたかったのが、データのグラフ化である。もちろんエクセルで作成するのは簡単だし、PHPでもできるということは分かっていたが、せっかくなら、地図情報を作成するPerlスクリプトの拡張でグラフを作成したかった。

今回、自前パソコンのActive PerlだとGDモジュールが動作したので操作方法を抜き出し記録に留める事にする。

準備
  1. ActivePerlをインストールする
  2. エディタ
  3. GDモジュールの利用可否を確認
  4. フォントフォルダの確認
  5. カラー名
  6. その他の設定
グラフ作成
  1. データの取り込み
  2. グラフ作成
  3. 内容確認
結果
  1. スクリプト
  2. 作成したPNG画像

準備

ActivePerlをインストールする

省略。

エディタ

文字コード「UTF-8」が編集できるエディタ(TeraPadなど)を準備しておく。

GDモジュールの利用可否を確認

使用環境でGDモジュールが使用できるかどうかは、次のCGIファイルを設置し所定のパーミッションにしたあと実行すると良い。

#!/usr/local/bin/perl
use strict;
use warnings;
use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
warningsToBrowser(1);
use GD::Graph;

GDモジュールが使えない場合は、下記のようなエラーメッセージが表示される。

Can't locate GD/Graph.pm in @INC (
 @INC contains: /usr/local/lib/perl5/5.10.1/BSDPAN
 /usr/local/lib/perl5/site_perl/5.10.1/mach
 /usr/local/lib/perl5/site_perl/5.10.1
 /usr/local/lib/perl5/5.10.1/mach
 /usr/local/lib/perl5/5.10.1 .
) at test2.cgi line 6.
BEGIN failed--compilation aborted at test2.cgi line 6.

確認は checkGDmodule.cgi をクリック

フォントフォルダの確認

フォントフォルダというものを設定すると、グラフで日本語が使えるようになり文字サイズが有効になります。文字サイズが決まればグラフレイアウトがやりやすくなります。

  1. パソコンのフォントフォルダを調べる
    師匠のWindowsパソコンでは「C:\WINDOWS\Fonts」となるようです。
  2. CGIスクリプトに2行を加える
    パス名は、上記から円マークをバックスラッシュに変更すること!
use GD::Text;
GD::Text->font_path("C:/WINDOWS/Fonts");

GD::Text->font_path("C:\WINDOWS\Fonts");と円マークを使うと動作しなかった。

カラー名

参考文献では「rgb.txtを呼び出す」と書いてあるが、cgiファイルが設置されているフォルダに「rgb.txt」を置いておけば良いようであった。

  1. CPAN Graph.pmを訪問
  2. ページ右のダウンロード項目にある圧縮ファイルをダウンロード
    2011/4/24では「GDGraph-1.44.tar.gz」であった
  3. 多機能圧縮・解凍ソフトで解凍する(+Lhacaなど)
  4. GDGraph-1.44 \ samplesフォルダを開く
    rgtb.txtが見つかる
  5. CGIスクリプトで読み込みたいパスにコピーペーストする
  6. 元の圧縮ファイル・解凍後フォルダは削除してもかまわない

CGIファイルと同じフォルダにコピーした場合のスクリプトは以下のようになる。

GD::Graph::colour::read_rgb( "rgb.txt" ) or die( "Can't read colours" );

カラー名が使えるようになって、グラフの作成に愛着が出るようになった。具体的なrgb.txtはこちらだが、rgb.txtの色一覧表を見ながら、色選定して欲しい。なお、rgb.txtは定義文なのであるから、書式さえあっていれば、自分好みの色名とRGB値を作成することも可能と考える。

その他の設定

その他で読み込んでおくモジュールは、Jcodeぐらいだと思う。Active Perl 5.12.3だと標準のモジュールにないと思うので、次からダウンロードして、Perlスクリプトと同じ場所に Jcode.pm を設置するといいようだ。

ダウンロード先
Jcode.pm
インストール方法
師匠は、スクリプトと同じディレクトリにJcode.pmをコピーするだけで動作したが、正しい方法なのかどうかはわからない
Jcode.pmを削除するとエラーになったので、標準ライブラリではないようだ
use Jcode;

グラフ作成

データ取り込み

GDモジュールでグラフ化するデータは、1つの項目配列と1つ以上のデータ配列からなる。山歩きのGPXデータからCSVファイルを生成していたので、これをさらに加工してグラフデータを作成することにする。

# track__.csv を読み込み、元配列に格納する
# num  Lat       Lng        2点間距離 m   高さm  年月日     時刻    2点間秒数 s
#   1  36.416655 139.411278 36.28951611    244  2011/4/17 8:14:27         65

my (@alldata,@length,@speed,@height,@clock,@totaltime);
my $readfile ="../sanpo2011/20110417-sennin/track20110417.csv";   # 読み込みデータ
  open(IN,"$readfile") || error("$readfileが読み出しできません"); 
  @alldata = <IN>;
close(IN);
my ($num,$lat,$lng,$length,$height,$date,$clock,$seconds);
my $totalkm=0; my $totaltime=0; my $speed;
foreach (@alldata) {                                              # 切り出し
  chomp();
  ($num,$lat,$lng,$length,$height,$date,$clock,$seconds)=split (/\,/,$_); 
  $totalkm += $length/1000.0;
  push (@length,$totalkm);
  push (@height,$height);
  push (@clock,$clock);
  if ($seconds!=0) {
    $speed = $length*3600/$seconds/1000;                          # ゼロでの除算を回避
  } else {
    $speed = 0;
  }
  $totaltime += $seconds/60;                                      # 経過時間 分
  push (@totaltime,$totaltime);
  push (@speed,$speed);
}
# 「距離、速度、高さ」をデータにする場合
@alldata = ( \@length, \@speed, \@height ) # データ生成完了 \記号に注意

参考文献によっては、Perlデータ構造体などという難しい表現が出てくるかもしれないが、ここでは気にせず進むことにする。

グラフ作成

さて、データ準備ができたので、ここでは横軸を距離にとった折れ線グラフを作成する手順を説明するY軸データは2つあるため、Y軸を左右2つに設置する。。

my $graph = GD::Graph::lines->new( 800,400 );

横800ピクセル、縦400ピクセルの折れ線グラフを定義する書式である。

  1. lines:折れ線グラフ
  2. points:点グラフ
  3. linespoints:点付折れ線グラフ
  4. bars:棒グラフ
  5. hbars:水平棒グラフ
  6. areas:面グラフ
  7. mixed:混合
  8. pie:円グラフ
$graph->set_text_clr("black");                 # 文字色は黒
$graph->set_title_font( "HGRGM.TTC", 14 );
$graph->set_legend_font( "HGRGM.TTC", 12 );
$graph->set_x_axis_font( "HGRGM.TTC", 12 );
$graph->set_y_axis_font( "HGRGM.TTC", 12 );
$graph->set_x_label_font( "HGRGM.TTC", 12 );
$graph->set_y_label_font( "HGRGM.TTC", 12 );

文字色、文字フォント、文字サイズを設定。メインの書式を定義する。
師匠のパソコンWindowsXPに入っていたフォントには以下のようなものがあった。MSGOTHIC.PPT(MSゴシック)なら万能だと考えていたが、フォントサイズによっては文字化けが発生したため、HGゴシックMなどを使うと解消した。

$graph->set( title            => jcode("2011年4月17日(日) 仙人ヶ岳・赤雪山")->utf8,
             t_margin         => 10, # topマージン px
             b_margin         => 10, # bottomマージン px
             l_margin         => 20, # left
             r_margin         => 20, # right
             types            => [ qw(lines lines) ], # タイプを列挙
             dclrs            => [ qw(red blue ) ], # グラフの色を列挙
             boxclr           => "aliceblue", # グラフ内の背景色
             fgclr            => "black",     # 全景色 枠の色?
             bgclr            => "white",     # グラフの背景色
             two_axes         => 1,           # 2軸
             x_label          => jcode("ハイキング距離 km")->utf8, # x軸ラベル
             x_label_position => 0.5,         # x軸ラベルの場所 0.5 = 半分
             y1_label         => jcode("速度 km/h")->utf8, # y軸ラベル
             y2_label         => jcode("標高 m")->utf8, # y軸ラベル
        #    long_ticks       => 1,   # 軸を長くする場合 1、デフォルトは0=短い
        #    x_ticks          => 1,   # x軸を表示しない 1、デフォルトは0=表示する
             y1_max_value     => 8,   # y1軸の最大値
             y2_max_value     => 800, # y2軸の最大値
             y1_min_value     => 0,   # y1軸の最小値
             y2_min_value     => 0,   # y軸の最小値
             x_max_value      => 14,  # x軸の最大値
             y_tick_number    => 8,   # Y軸を刻む数
             x_tick_number    => 14,  # x軸を刻む数
             y_label_skip     => 2,   # y軸ラベルの飛び数
             x_label_skip     => 2,   # x軸ラベルの飛び数
             line_width       => 2,   # 線幅
             cumulate         => 1
           );

最後に画像を作成する。ここでは、PNG形式画像を作成した。出力するスクリプトの書式は何通りかあるようだが、ここでは本形式のみ記載しておく。

my $image = $graph->plot( \@alldata ) or die( "Cannot create image" );

open( OUT, "< graph-speed.png") or die( "Cannot open file" );
binmode OUT;
print OUT $image->png();  # PNG形式で出力
close OUT;

参照

参照の一部を表示する。上記の参考サイトなどを見てもらったほうが早いと思う。

title グラフのタイトル
types mixed タイプのグラフの場合、各データをどの種類のグラフにするか無名配列でリストする
t_margin Top マージン (デフォルト 0)
b_margin Bottom マージン(デフォルト 0)
l_margin Left マージン(デフォルト 0)
r_margin Right マージン(デフォルト 0)
x_label_position X軸ラベルの位置(0〜1)、デフォルト 3/4
y_label_position Y軸ラベルの位置(0〜1)、デフォルト 1/24
x_label X軸ラベルの内容
y_label Y軸ラベルの内容
x_min_value X軸の最小値
x_max_value X軸の最大値
two_axes Y軸が2軸の場合 1 (デフォルト 0)
y_min_value Y軸の最小値 2軸の場合は,y1_min_valueとy2_min_valueとなる
y_max_value Y軸の最大値 2軸の場合は,y1_max_valueとy2_max_valueとなる
x_tick_number X軸ラベルの分割数
y_tick_number Y軸ラベルの分割数
x_label_skip X軸ラベルのスキップ
y_label_skip Y軸ラベルのスキップ
line_types 線グラフの線の種類を無名配列でリストする( 1:実線 / 2:ダッシュ / 3:点線 / 4:点線 )
line_width 線グラフの太さ
markers 点、点付折れ線グラフで使われる点の種類を無名配列でリストする
( 1:塗り四角 / 2:四角 / 3:十字 / 4:クロス十字 / 5:塗り菱形 / 6:菱形 / 7:塗り丸 / 8:丸 )
marker_size 点、点付折れ線グラフで使われる点のサイズ(デフォルト 4)
bar_width 棒グラフの幅
bar_spacing 棒グラフ間の幅
bgclr グラフの背景色
fgclr グラフの前景色
boxclr グラフ内の背景色
dclrs グラフの色を無名配列でリストする
accentclr グラフの外枠の色
shadowclr グラフの影の色
shadow_depth グラフの影の幅
transparent 1 だと透明色となる (デフォルト 1)
interlaced 1 だとインターレース画像となる (デフォルト 1)
cumulate データセットが積算される(棒グラフ、面グラフ)

作成結果

スクリプト

実際にグラフを作成したスクリプトを紹介する。サーバー上では下記CGIファイルはテキスト表示されると思う。
makeGraphGD.cgi / makeGraphGD2.cgi

画像

下記は、2012/8/25皇海山の山行における、横軸距離および時間としたときの、縦軸標高・速度のグラフです。


横軸:距離、縦軸:標高

横軸:距離、縦軸:速度

横軸:時間、縦軸:標高

横軸:時間、縦軸:速度

Topに戻る // 戻る
Copyright(C) Grandmaster since 2010最終更新:2015/5/15