ファイヤープロジェクト
関数のグラフの作成(JFreechart 0.9.16)
2004-02-11T17:00+09:00   matsu
JFreeChartを使用して関数のグラフを作成してみた.
本頁で作成するグラフは,DatasetからXとYの値の組を取得して,それらを線で結ぶグラフである.以下便宜上XYLineChartと呼ぶ.XYLineChartを使用すると,ある関数を定義して,そのグラフを作成することができる.以下XYLineChartを作成,表示するサンプル.
今回の主な登場クラスを整理しておく.
今回は,以下の三つのメソッドでJFreeChartがらみの処理を行なっている.
  • workXYLineChart
  • getXYLineChart
  • configXYLineChart
workXYLineChartは棒グラフの頁のサンプルとほとんど同じであるので,本頁では説明を省略する.また,このサンプルでは,自作のDatasetであるMyXYDatasetを使用する.
詳細は次節以降に記述するとして,サンプルを実行して作成されたPNG画像を以下に示す.
サンプルでは,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にした場合は縦軸と横軸を読み返る必要がある.
matsu(C)
Since 2002
Mail to matsu