散布図の描画
JavaFXサンプルプログラム
散布図を描くプログラムをJavaFXで作ってみた。データをプログラムソースコード内に書く簡単なものと、データをファイルから読み込む場合の2つを作成した。
データをプログラム(リスト1)内に書いたものを実行すると図1の散布図が描かれる。
図1
=================== リスト1(始まり) ===================
package ScattergramS;
import java.io.*;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.chart.*;
import javafx.scene.layout.*;
import javafx.stage.*;
public class ScattergramS extends
Application {
static
double sqr( double x ){
return
x * x;
}
@Override
public
void start(Stage stage){
//
// データの設定
//
double
data[][] = { {1, 5},
{2,
4},
{3,
2},
{5,
1} };
int
n = data.length;
String
Var1Label = "X1"; // 横軸の変数名
String
Var2Label = "X2"; // 縦軸の変数名
/*---------------------------------------------------
散布図の描画
-----------------------------------------------------*/
stage.setTitle("散布図");
NumberAxis
x_axis = new NumberAxis();
x_axis.setLabel(Var1Label);
NumberAxis
y_axis = new NumberAxis();
y_axis.setLabel(Var2Label);
XYChart.Series<Number,
Number> xy_series = new XYChart.Series<>();
xy_series.setName("("
+ Var1Label + ", " + Var2Label + ")");
for
(int i = 0; i < n; i++)
xy_series.getData().add(new
XYChart.Data<>(data[i][0], data[i][1]));
ScatterChart<Number,
Number> scatter = new ScatterChart<>(x_axis, y_axis);
scatter.setTitle("散布図");
scatter.getData().add(xy_series);
HBox
root = new HBox();
root.getChildren().add(scatter);
stage.setScene(
new Scene(root, 800, 600) );
stage.show();
}
}
======================== りすと1(終わり) ========================
データは、配列の初期値として以下のように設定されている。
double
data[][] = { {1, 5},
{2,
4},
{3,
2},
{5,
1} };
int n = data.length;
散布図の描画で用いる変数名は
String
Var1Label = "X1"; // 横軸の変数名
String Var2Label = "X2"; // 縦軸の変数名
と設定して、NumberAxis型のオブジェクトx_axisとy_axisに設定している。
NumberAxis
x_axis = new NumberAxis();
x_axis.setLabel(Var1Label);
NumberAxis
y_axis = new NumberAxis();
y_axis.setLabel(Var2Label);
リスト1のプログラムは圧縮ファイルScattergramS.zipにまとめた。圧縮ファイル名ScattergramS.zipをクリックしてダウンロード・展開すればエディタで開くことが出来る。プログラムはWindows上で作成されたので、ubuntuなどで利用すると日本語コードの違いによるエラーが出る。日本語コードの変換については、別のウェブサイトで説明している。
プログラムは、別のウェブサイトで説明している相関係数の計算プログラムに、散布図の描画を追加して作成した。実行したときの散布図は図2のようになる。
図2
プログラムは、リスト2に示す。
======================== リスト2(始まり) =====================
package Scattergram;
import java.io.*;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.chart.*;
import javafx.scene.layout.*;
import javafx.stage.*;
import ExtractSubString.*; // 区切り文字で区切られた部分文字列の取り出し用パッケージ
import CalcStats.*; // 統計量算出用クラス型 CalcStats が宣言されている
public class Scattergram extends
Application {
static
double sqr( double x ){
return
x * x;
}
@Override
public
void start(Stage stage){
try{
//
// キーボード入力をバッファー付きで設定
//
BufferedReader
cin = new BufferedReader( new InputStreamReader(System.in) );
System.out.print("Input
Data File = ");
//
// 入力データファイルの設定
//
String
fin_nm = cin.readLine();
BufferedReader
fin = new BufferedReader( new FileReader(fin_nm));
//
// 出力用テキストファイルの設定
//
System.out.print("Output
File Name = ");
String
fout_nm = cin.readLine();
PrintWriter
fout = new PrintWriter( new BufferedWriter( new FileWriter(fout_nm)));
double
data[][] = new double[1000][2];
ExtractSubString
Extrct = new ExtractSubString(); // 部分文字列取り出し用オブジェクト
char
ck_c[] = { ' ', '\t', '\n', ',', '\f', '\r' }; // 区切り文字の選択
Extrct.ck_list
= ck_c; // 区切り文字のオブジェクトへの設定
int
n = 0;
while(true){
String
s = fin.readLine();
if(s.length()
> 0)
if
(s.charAt(0) == '/') // スラッシュ / で始まる行まで読み進む
break;
}
String
s = fin.readLine();
Extrct.CheckStr(s);
String
Var1Label = Extrct.getStrR(0);
String
Var2Label = Extrct.getStrR(1);
while(true){
s
= fin.readLine();
if
(s.charAt(0) == '/') break; // スラッシュ / で始まる行で読み込みの終了
Extrct.CheckStr(s); // s
に読み込んだ文字列をE xtrct に設定
data[n][0]
= Double.parseDouble(Extrct.getStrR(0)); // 1
番目のデータの取り出し。最初のデータは
0 番目の数える
data[n][1]
= Double.parseDouble(Extrct.getStrR(1)); // 2
番目のデータの取り出し
n++;
}
fin.close();
fout.println("Data...");
for
(int i = 0; i < n; i++){
//
// 読み込んだデータの確認用出力
//
System.out.println("data["
+ i + "][0] = " + data[i][0]
+
" data[" + i +
"][1] = " + data[i][1]);
fout.println("data["
+ i + "][0] = " + data[i][0]
+
" data[" + i +
"][1] = " + data[i][1]);
}
fout.println();
//
// 統計量算出用クラス型 CalcStats のオブジェクト calc の宣言
//
CalcStats
calc = new CalcStats( data, n );
calc.calc(); // 相関係数などの算出
String
fs = String.format("mean0 = %-9.5f mean1 = %-9.5f",
calc.mean0, calc.mean1);
fout.println(fs);
fs
= String.format("var0 = %-9.5f var1 = %-9.5f",
calc.variance0, calc.variance1);
fout.println(fs);
fs
= String.format("SD0 = %-9.5f
SD1 = %-9.5f", calc.sd0, calc.sd1);
fout.println(fs);
fs
= String.format("Covarinace = %-9.5f", calc.cov);
fout.println(fs);
fs
= String.format("r = %-9.5f", calc.r);
fout.println(fs);
fout.close();
/*---------------------------------------------------
散布図の描画
-----------------------------------------------------*/
stage.setTitle("散布図");
NumberAxis
x_axis = new NumberAxis();
x_axis.setLabel(Var1Label);
NumberAxis
y_axis = new NumberAxis();
y_axis.setLabel(Var2Label);
XYChart.Series<Number,
Number> xy_series = new XYChart.Series<>();
xy_series.setName("("
+ Var1Label + ", " + Var2Label + ")");
for
(int i = 0; i < n; i++)
xy_series.getData().add(new
XYChart.Data<>(data[i][0], data[i][1]));
ScatterChart<Number,
Number> scatter = new ScatterChart<>(x_axis, y_axis);
scatter.setTitle("散布図 " +
String.format("r = %-9.5f", calc.r) );
scatter.getData().add(xy_series);
HBox
root = new HBox();
root.getChildren().add(scatter);
stage.setScene(
new Scene(root, 800, 600) );
stage.show();
}
catch(Exception
e){
System.out.println("Exception..."
+ e);
System.exit(1);
}
}
}
======================== リスト2(終わり) =====================
描画のためのコード以外は、別のウェブサイトで説明しているのでそちらを参照されたい。
散布図の描画の部分は、十数行の長さである。
プログラムを実行すると別のウェブサイトのプログラムの場合と同じように入力データファイル名の設定が求められる(図3)。
図3
本ウェブサイトのプログラムでは、散布図に用いる変数名のデータも入力データファイルに書き込んでおく必要がある。すなわち、最初のスラッシュ / で始まる行の次の行(図4では3行目)に変数名を並べて書いておく。変数名のデータの追加を除いて、別のウェブサイトのプログラムの場合と同じである。
図4
プログラムを圧縮ファイルScattergram.zipとしてまとめたものも用意した。圧縮ファイル名Scattergram.zipをクリック・ダウンロード・展開すればエディタで開いてみることが出来る。ただし、プログラムはWindows上で開発されたものであるので、ubuntuなどで利用するときは日本語コードの変換を行う必要がある。日本語コードの変換については、別のウェブサイトで説明している。