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名)を生成してみた。