
PHPでMySQLデータベースのレコード数の度数分布を取得し、pChartを利用してヒストグラム画像を生成してみた。
度数の取得
例えば、データベース名DataBaseNameからValueが10以上20以下のレコード数を取得するSQL文は以下。
SELECT count(*) from DataBaseName where Value >= 10 and Value<= 20
上記を繰り返し実行して度数を取得していけばよさそうだ。
function GetHistGram()
{
//度数取得範囲、ステップ
$val_start = 0;
$val_step = 25;
$val_max = 500;
while($val_start < $val_max)
{
$val_end = $val_start + $val_step;
//SELECT文の実行
$sql = "SELECT count(*) from DataBaseName where Value>= ". $val_start. " and Value< ". $val_end;
$result = mysql_query($sql);
if($result == false)
{
PrintAndWriteLog("失敗<br>\n");
return;
}
//1レコード取得
$row = mysql_fetch_array($result);
//グラフ用にArrayに追加する
$Graph_X[] = $val_start. "-". ($val_end-1); //範囲 :X軸表示文字列
$Graph_Y[] = $row[0];//度数 :Y軸の値
//単なるログ表示
PrintAndWriteLog("Hist[".$val_start."][".($val_end-1)."] = ".$row[0]."<br>\n");
//次の度数取得へ
$val_start += $val_step;
}
//pChartを利用したグラフ画像作成
MakeChart($Graph_X, $Graph_Y);
//手っ取り早く画像を表示させるには以下を有効に。
//echo '<img src="./example3.png">';
}
//標準出力及びログファイルへ出力
function PrintAndWriteLog($buf)
{
$LOG_FILE_NAME = "hoge.txt";
//日付
$date = date('Y/m/d(D) H:i', time());
//標準出力へ出力
echo $date." ".$buf;
//標準出力へ出力(SJIS)
//コマンドプロンプトで動作時、文字化けする場合などはSJISに変換して表示
//echo mb_convert_encoding($buf, "SJIS", "UTF-8");
//ログファイルへ追記
$fp = fopen($LOG_FILE_NAME, "a+");
fputs($fp, $date." ".$buf);
fclose($fp);
}
以下のような度数分布ログが取得できたらしめたものである。
2011/11/28(Mon) 21:26 Hist[1][25] = 207466 2011/11/28(Mon) 21:26 Hist[26][50] = 39831 2011/11/28(Mon) 21:26 Hist[51][75] = 21731 2011/11/28(Mon) 21:26 Hist[76][100] = 13788 2011/11/28(Mon) 21:26 Hist[101][125] = 10311 2011/11/28(Mon) 21:26 Hist[126][150] = 7562 2011/11/28(Mon) 21:26 Hist[151][175] = 5695 2011/11/28(Mon) 21:26 Hist[176][200] = 4637 2011/11/28(Mon) 21:26 Hist[201][225] = 3836 2011/11/28(Mon) 21:26 Hist[226][250] = 3061 2011/11/28(Mon) 21:26 Hist[251][275] = 2711 2011/11/28(Mon) 21:26 Hist[276][300] = 2233 2011/11/28(Mon) 21:26 Hist[301][325] = 1864 2011/11/28(Mon) 21:26 Hist[326][350] = 1601 2011/11/28(Mon) 21:26 Hist[351][375] = 1374 2011/11/28(Mon) 21:26 Hist[376][400] = 1154 2011/11/28(Mon) 21:26 Hist[401][425] = 1086 2011/11/28(Mon) 21:26 Hist[426][450] = 995 2011/11/28(Mon) 21:26 Hist[451][475] = 905 2011/11/28(Mon) 21:26 Hist[476][500] = 746
グラフの作成
せっかく度数分布が取得できたので、ヒストグラム画像まで生成したい。
今回はPHPベースのグラフ生成ライブラリpChartのサンプル”example3″を少し改造して使ってみた。
改造には、pChartの部屋さんが参考になった。
X軸データには”Value”、Y軸データには”Frequency”と名前を付けている。
function MakeChart($Graph_X, $Graph_Y)
{
/*
Example3 : an overlayed bar graph, uggly no?
*/
// Standard inclusions
include("./pChart/pData.class");
include("./pChart/pChart.class");
// Dataset definition
$DataSet = new pData;
//描画データの設定
//$DataSet->AddPoint(array(1,4,-3,2,-3,3,2,1,0,7,4,-3,2,-3,3,5,1,0,7),"Serie1");
//$DataSet->AddPoint(array(0,3,-4,1,-2,2,1,0,-1,6,3,-4,1,-4,2,4,0,-1,6),"Serie2");
$DataSet->AddPoint($Graph_X,"Value");
$DataSet->AddPoint($Graph_Y,"Frequency");
//X軸の値は数値でなく見出し文字列として表示
$DataSet->SetAbsciseLabelSerie("Value");
$DataSet->AddAllSeries();
//$DataSet->SetAbsciseLabelSerie();
//$DataSet->SetSerieName("January","Serie1");
//$DataSet->SetSerieName("February","Serie2");
// Initialise the graph
$Test = new pChart(1280,960);
$Test->setFontProperties("./Fonts/tahoma.ttf",8);
$Test->setGraphArea(50,30,1200,900);
//$Test->drawFilledRoundedRectangle(7,7,693,223,5,240,240,240);
//$Test->drawRoundedRectangle(5,5,695,225,5,230,230,230);
$Test->drawGraphArea(255,255,255,TRUE);
$Test->drawScale($DataSet->GetData(),$DataSet->GetDataDescription(),SCALE_NORMAL,150,150,150,TRUE,0,2,TRUE);
$Test->drawGrid(4,TRUE,230,230,230,50);
//値を表示
$Test->setFontProperties("./Fonts/tahoma.ttf",8);
$Test->writeValues($DataSet->GetData(),$DataSet->GetDataDescription(),"frequency");
// Draw the 0 line
$Test->setFontProperties("./Fonts/tahoma.ttf",6);
$Test->drawTreshold(0,143,55,72,TRUE,TRUE);
// Draw the bar graph
$Test->drawOverlayBarGraph($DataSet->GetData(),$DataSet->GetDataDescription());
// Finish the graph
$Test->setFontProperties("./Fonts/tahoma.ttf",8);
$Test->drawLegend(600,30,$DataSet->GetDataDescription(),255,255,255);
$Test->setFontProperties("./Fonts/tahoma.ttf",10);
$Test->drawTitle(50,22,"Nicommunity frequency distribution chart",50,50,50,585);
$Test->Render("example3.png");//PNGファイルとして出力される
}
以下が作成したヒストグラム画像。
題材としてコミュサーチのデータベースから、
コミュニティメンバーが500名以下のコミュニティのヒストグラム(幅:25名)を生成してみた。
