関数のグラフの作成(JFreechart 0.9.16)
JFreeChartを使用して関数のグラフを作成してみた.
本頁で作成するグラフは,DatasetからXとYの値の組を取得して,それらを線で結ぶグラフである.以下便宜上XYLineChartと呼ぶ.XYLineChartを使用すると,ある関数を定義して,そのグラフを作成することができる.以下XYLineChartを作成,表示するサンプル.
今回の主な登場クラスを整理しておく.
今回は,以下の三つのメソッドでJFreeChartがらみの処理を行なっている.
詳細は次節以降に記述するとして,サンプルを実行して作成されたPNG画像を以下に示す.
- workXYLineChart
- getXYLineChart
- configXYLineChart
サンプルでは,XYLineChartの作成をgetXYLineChartメソッド内で行なっている.表示データは単にMyXYDatasetオブジェクトをnewするだけである.
// XYDatasetオブジェクトの作成 XYDataset xyData = new MyXYDataset();MyXYDatasetについては次節で記述する.これを使用してChartFactoryでXYLineChartを作成する.
// XYDatasetをデータにしてJFreeChartを作成
JFreeChart xyLineChart = ChartFactory.createXYLineChart ("SampleXYLineChart",
"domain",
"range",
xyData, PlotOrientation.VERTICAL,
true, true, true);
第一引数はグラフのタイトル,第二引数は横軸の説明,第三引数は縦軸の説明,第四引数は表示データである.第五引数により,縦グラフ(PlotOrientation.VERTICAL)か横グラフ(PlotOrientation.HORIZONTAL)かを指定する.縦グラフならX軸が横軸,Y軸が縦軸となり,横グラフならそれらが反転する.最後三つはcreatePieChartと同様.
今回はXYLineChartの表示データを格納するクラスMyXYDatasetを自作した.これはXYLineChartの肝である.MyXYDatasetはインタフェースXYDatasetとアブストラクトクラスAbstractSeriesDatasetを実装する(※).MyXYDatasetを理解する上で重要なポイントが二つある.
- 媒介変数
- XYDatasetでは,グラフを作成する関数をintの媒介変数で表現する.上位は媒介変数を0からgetItemCountメソッドで(上位が)取得した値まで1ずつ変化させながら,getXValue,getYValueで座標(X,Y)を取得して線を引いていく.
- シリーズ
- XYDatsetとAbstractSeriesDatasetでは,シリーズという概念がある.これは一つのDatasetオブジェクトにグラフに表示する複数の関数のデータを格納するための概念である.関数は0から始まるシリーズの番号を指定することで特定する.
x = r * cos(t) y = r * sin(t)上位はtを指定して,XとYを取得する.
public Number getXValue (int series, int item) public Number getYValue (int series, int item)このとき上位はtは0から以下の関数の返り値まで1ずつ変化させる.
public int getItemCount (int series)この仕様を考慮しつつ,getXValue,getYValueを作成する必要がある.また,今回は一つのMyXYDatasetオブジェクトから二つの関数のデータを取得することができる.これにはシリーズの概念を使用する.すなわちgetXValue,getYValueにおいて,指定されたシリーズによって別の値を返すようにする.
public Number getXValue (int series, int item) {
return new Double (radius[series] * Math.cos(item / (10.0)));
}
public Number getYValue (int series, int item) {
return new Double (radius[series] * Math.sin(item / (10.0)));
}
ここでは動作に違いはないが,上位が媒介変数の上限を知るためのメソッドgetItemCountでも,上位はシリーズを指定してくるので,シリーズ毎に媒介変数の閾値を変更することもできる.上位は全てのシリーズに対するグラフを描画するために,以下の関数でシリーズ数を取得する.
public int getSeriesCount () {
return seriesCount;
}
これにより,上位は0から(シリーズ数 - 1)まで変化させる.また,上位はグラフの説明に使用するシリーズ毎の名前を以下の関数で取得する.
public String getSeriesName (int series) {
return "MyXYDatasetSeries" + series;
}
先のグラフ出力でも,下部にこれらが表示されている.
※ いろいろと複雑な事情があるようで,両方を実装するのが一番手っ取り早いと思う.
サンプルではconfigXYLineChartメソッドで,グラフの軸に関する設定を行なっている.軸はXYLineChartのXYPlotオブジェクトから取り出す.XYLineChartでは,縦軸,横軸ともに縦軸はValueAxisクラスとなっている.縦軸の取得メソッドはgetDomainAxis,横軸を取得するメソッドはgetRangeAxisである(※).
XYPlot xyPlot = xyLineChart.getXYPlot(); ValueAxis xAxis = xyPlot.getDomainAxis(); .... ValueAxis yAxis = xyPlot.getRangeAxis();取得したValueAxisについては棒グラフのときにも記述した.今回もAutoRangeを無効にして,軸毎にRangeを指定している.
xAxis.setAutoRange(false); xAxis.setRange(-8.0, 27.0); .... yAxis.setAutoRange(false); yAxis.setRange(-20.0, 15.0);setRangeで指定する幅が縦軸と横軸でことなると,縦長あるいは横長のグラフになるので,場合によっては注意が必要である.
※ この文脈もcreateXYLineChartの第五引数をPlotOrientation.HORIZONTALにした場合は縦軸と横軸を読み返る必要がある.

