java-beginner.com ブログ

プログラミングを学習するブログ(Javaをメインに)

度数分布図をJavaFXで描画

投稿日:

最終更新日:2016年08月06日

アイキャッチ

こんにちは。「Javaを復習する初心者」です。今回はFavaFXで度数分布図を描画しました。

JavaFXではグラフ描画用のクラスが用意されています。そのうちのBarChartクラスを使いました。

JavaFX開発環境

JavaFXのアプリケーションをEclipseで開発するためにはe(fx)clipse というJava FX用のプラグインを使います。しかし、いつも使っているMarsでは何故かエラーが出てしまい、インストールできませんでした。なので、今回の開発環境は以下のEclipseです。

  • Eclipse Java EE IDE for Web Developers.
  • Version: Luna Service Release 2 (4.4.2)
  • Build id: 20150219-0600

上記にe(fx)clipse – IDEプラグインをインストールしました。

今回は3つの系列の棒グラフを作成しました。

系列1つの場合のサンプルはQiitaに挙げました。
https://qiita.com/java-beginner/items/d02599c0170b90ffe852

ソースと実行結果

ソースは以下です。

ソースコード

package practice;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Series;
import javafx.stage.Stage;

public class Hello20160806 extends Application {

	// 系列ラベル
	private static final String[] seriesNames = {
		"A",
		"B",
		"C"
	};

    // 項目ラベル
    private static final String[] dataLabels = {
            " 0~ 9点",
            "10~19点",
            "20~29点",
            "30~39点",
            "40~49点",
            "50~59点",
            "60~69点",
            "70~79点",
            "80~89点",
            "90~99点",
            "   100点",
    };

    // 人数を格納した配列を返却
    private int[] getCounts() {

        // 点数をランダムで格納
        int[] points = new int[1000];
        Random random = new Random();
        for (int i = 0; i < points.length; i++) {
            points[i] = random.nextInt(101);
        }

        // 集計
        int[] counts = new int[11];
        for (int point : points) {
            counts[ point / 10 ] ++;
        }

        return counts;
    }

    @Override
	public void start(Stage primaryStage) throws Exception {


        // 系列を生成
        List<Series<Number, String>> seriesList = new ArrayList<XYChart.Series<Number,String>>();

        for (String seriesName : seriesNames) {

        	int[] counts = getCounts();

            Series<Number, String> series = new Series<Number, String>();
            series.setName(seriesName);
            for (int i = 0; i < dataLabels.length; i ++) {
            	series.getData().add(new XYChart.Data<>(counts[i], dataLabels[i]));
            }
            seriesList.add(series);

        }

        // 軸を作成
        NumberAxis numberAxis = new NumberAxis();
        numberAxis.setLabel("人数");
        CategoryAxis categoryAxis = new CategoryAxis();
        categoryAxis.setLabel("点数");

        // 棒グラフを生成
        BarChart<Number, String> bc = new BarChart<>(numberAxis, categoryAxis);
        bc.setBarGap(2);
        bc.setCategoryGap(4);
        bc.getData().addAll(seriesList);

        // Scene
        Scene scene  = new Scene(bc, 400, 400);

        // Stage
		primaryStage.setTitle("得点分布図");
		primaryStage.setScene(scene);
		primaryStage.show();

	}

	public static void main(String[] args) {
        launch(args);
    }

}

棒グラフ作成の手順は以下の通りです。

系列を作成:データの設定にはXYChart.Series<X,Y>クラスを使います。ジェネリックスのX, Yは軸を表すのですが、NumberとStringの組み合わせを指定するようです。グラフの生成を後ほどしますが、その時もジェネリックスがあります。そこで同じ組合せを指定します。組み合わせによって、グラフの縦横が決定します。setName(String value)でプロパティnameの値を設定します。このプロパティは「このシリーズのユーザー表示名」とAPI仕様書には記載してあります。「系列」といった方が慣れていると思います。

軸を作成:NumberAxisクラスのインスタンスを生成します。この軸は数値軸です。setLabelメソッドでプロパティlabelの値を設定することができます。もう一つの軸として、CategoryAxisクラスのインスタンスを生成します。区分のための軸です。setLabelメソッドが使えるのでラベルを設定します。

棒グラフを生成:BarChart<X,Y>クラスがカテゴリのデータ値を示す棒をプロットするチャートです。ジェネリックスの組み合わせは上記のXYChart.Series<X,Y>のインスタンスを作った箇所と同じにします。setBarGap(double value)でプロパティbarGapの値を変更します。このプロパティは「同じカテゴリのバーの間に残す間隔」です。初期値は4.0のようです。今回は2にしてみました。setCategoryGap(double value)でプロパティcategoryGapの値を変更します。このプロパティは「異なるカテゴリのバーの間に残す間隔」です。初期値は10.0のようです。今回は4にしてみました。barGapとcategoryGapの値の組み合わせでグラフが細くなったりします。

以下は実行結果です。

BarChart

3つの系列のグラフが描画されました。色は自動的にこの色になるようです。数値の範囲も自動的に設定されるようです。