2006/05/03(水)Perl

久々に触ったけど、Perl難しいよPerl。

Perlのポケットリファレンスどっかいっちゃったので、使ったWebページをメモ。

http://www.rfs.jp/sb/perl/index.html

http://www2u.biglobe.ne.jp/~MAS/perl/ref/index.html

http://www.nwt.jp/document/perlfunc/index.htm

http://pub.cozmixng.org/~the-rwiki/rw-cgi.rb?cmd=view;name=%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8%B8%C0%B8%EC%A4%CE%C8%E6%B3%D3#header-navi
[わからないこと、いやなこと]

・$x と @x が違う変数なのはもちろんいいんだけど、@xの要素にアクセスするときに$x[]なのがちょっと気持ち悪い。

が嫌。なぜここだけ<>?

・あとスカラーで評価されるタイミングがよく分からない。

・破壊的代入ばっか……

・クラス・構造体の実装が無理しすぎに見える。
改めて思う、Rubyは楽ね。

2006/05/03(水)GD::Graphのあれこれ(Perl)

あまり他で書いてないことをいくつか。

GD::Graphの生成画像にイメージマップを貼る


GD::Graph::Mapを使う手もあるがどうも使い勝手が悪い。そこでhotspot()メソッドを使う。
use GD::Graph::points;
my $graph = GD::Graph::points->new(400,300);

@data = (
	['1st', '2nd', '3rd'],
	[1, 2, 3],
);

my $image = $graph->plot(\@data) or die;
my @ret = $graph->get_hotspot(1);
for(my $i = 0; $i < @ret; $i++) &#123;
	print "<area shape=$ret[$i][0] Coords=$ret[$i][1],$ret[$i][4],$ret[$i][2],$ret[$i][3]>\n";
&#125;
こんな感じで。第1引数はデータ系列番号(1始まり)、第2引数はデータ系列中のデータ番号(0始まり)。共に省略可。

ソースをざっと見た限りでは、生成したグラフのタイプによってtop, bottom, left, rightがどの順で帰ってくるか違ってるような気がする。

プログラム作成時にテストした方がよい。
なお、どうでもいい話であるが、このメソッドいつも「ホッツポット」と読んでしまう。なんでだ?

numerical X(x軸を数字として扱う)


GD::Graphは基本では全てのXを見出しとして等価に扱う。

だが、散布グラフや1つの列に2つ以上のデータをプロットする場合など、X座標を数字として扱いたい機会は多い。

GD::Graphのマニュアルにあるとおりこの機能は本来はunsupportedである。従って、ちょっとやり方が複雑。


  1. x_min_value, x_max_value, x_tick_numberの3つを設定する

  2. データ系列が3つ以上の値を含む

  3. x軸のデータが全て数字


この3条件を満たすときに数字として扱ってくれるようだ。
use GD::Graph::points;
my $graph = GD::Graph::points->new(400,300);

@data = (
	[1 ,1, 10],
	[1, 2, 3],
);

$graph->set(
	x_min_value => 0,
	x_max_value => 30,
	x_tick_number => 10,
);

my $image = $graph->plot(\@data) or die;

open(OUT, ">test.png") or die;
binmode OUT;
print OUT $image->png();
close(OUT);
setメソッド中の3行はどれをコメントアウトしても表示がおかしくなると思う。

グラフ座標を画像のピクセル座標に変換


val_to_pixel()メソッドを使う。本来プライベートメソッドであるべきものを呼んでる気がするけども。
use GD::Graph::points;
my $graph = GD::Graph::points->new(400,300);

@data = (
	['1st', '2nd', '3rd'],
	[1, 2, 3],
);

my $image = $graph->plot(\@data) or die;
my $green = $image->colorAllocate(0, 255, 0);

my @p1 = $graph->val_to_pixel(1, 1);
my @p2 = $graph->val_to_pixel(3, 3);
$image->line(@p1, @p2, $green);

open(OUT, ">test.png") or die;
binmode OUT;
print OUT $image->png();
close(OUT);
(1,1)から(3,3)の間に直線を引く。numerical Xにした場合でもちゃんと動くようだ。

なお、普通の解説とかサンプルは下記参考サイトが詳しい。

お、Rubyにラッパーあるね。まだ触って無いけど。
[マニュアル]

http://search.cpan.org/~bwarfield/GDGraph-1.4307/Graph.pm
[サンプル]

http://x68000.q-e-d.net/~68user/webcgi/gd-graph.html

http://www.linkclub.or.jp/~ma3ki/webutil/gdgraph/howtograph.html
OK キャンセル 確認 その他