PHP MySQL 度数分布の取得、ヒストグラム画像の作成


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

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です