Up

散布図の描画

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_axisy_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などで利用するときは日本語コードの変換を行う必要がある。日本語コードの変換については、別のウェブサイトで説明している。

 

 

Up