2012年5月15日火曜日

JFreeChart、関数をプロットする

JFreeChart で関数をプロットする方法を紹介。
 
チャートを生成する大雑把な手順は
 
Function2D オブジェクトを生成する
Dataset オブジェクトを生成する
JFreeChart オブジェクトを生成して表示する
です。
 
Function2D インターフェース
 
JFreeChart で関数を表すには、 org.jfree.data.function.Function2D インターフェースを用います。 このインターフェースは引数から値を計算して返す getValue() メソッドのみ定義されています:
 
package org.jfree.data.function;
 
public interface Function2D{
    double getValue(double x);
}
このインターフェースを実装するクラスであれば、以下で見る方法でチャートを表示することができます:
 
import static java.lang.Math.*
 
// サブクラス
class HyperbolicSineFunction implements Function2D{
    @Override
    public double getValue(double x){
        return (exp(x) - exp(x))/2.0;
    }
}
 
// 無名クラス
Function2D cosh = new Function2D(){
    @Override
    public double getValue(double x){
        return (exp(x) + exp(x))/2.0;
    };
}
Groovy ではメソッドが1つしかないインターフェースはクロージャを用いて簡単にインスタンスを生成できます:
 
import static java.lang.Math.*
 
def tanh = { x -> (exp(2d*x) - 1) / (exp(2d*x) + 1) } as Function2D
Dataset オブジェクトの生成
 
Function2D オブジェクトから Dataset オブジェクトを生成するには org.jfree.data.general.DatasetUtilities#sampleFunction2D() メソッドを用います:
 
Function2D f = ...
double xmin = -1.0d;
double xmax = 1.0d;
int sampleCount = 1000;
String seriesKey = "Function"
 
XYDataset dataset = DatasetUtilities.sampleFunction2D(f, xmin, xmax, sampleCount, seriesKey);
この結果返される XYDataset オブジェクトは(JFreeChart 1.0.12 では) XYSeriesCollection クラスのインスタンスで、sampleCount で指定された個数のデータを持つ離散的なデータになっています*1。
 
JFreeChart 1.0.13 からは DatasetUtilities クラスに XYDataset オブジェクトを生成する sampleFunction2D() メソッドに加えて、XYSeries オブジェクトを生成する sampleFunction2DToSeries() メソッドも定義されています(Maven2 のリポジトリには今のところ 1.0.12 までしか配備されていないので、拙者はあまり使ってませんが)。 他のデータも同時に扱いたい場合にはこちらを使うと便利かと。
 
チャートの生成(と表示)
 
上記の方法で生成された XYDataset オブジェクトは離散的なデータの単なる XYDataset なので、ChartFactory#createXxxx() メソッドで JFreeChart オブジェクトを生成すれば普通にチャートが生成できます(詳細割愛)。
 
JFreeChart chart = ChartFactory.createXYLineChart("Function Plot", "X", "Y", dataset, PlotOrientation.VERTICAL, true, true, false);
ちなみに、ChartFactory.createScatterPlot() などでチャートを生成すると、跳び跳びのグラフが表示されます。
 
とりあえず、これで関数のプロットは完了。
 
ビルドイン関数
 
JFreeChart にはもともと定義されている関数が3つあります(1.0.12)
 
LineFunction2D
1次関数。 new LineFunction2D(a, b) によって1次関数 a+bx が生成される(ax+b ではない!)
PowerFunction2D
冪関数。 new PowerFunction2D(a, b) によって a*x^b (x^b は x の b 乗の意)が生成される。 b が負の値や非整数でも可。 ただし、b が非整数の場合は x は非負でないといけない(NaN が返される)。
NormalDistribution2D
正規分布関数。 new NormalDistribution2D(μ, σ) は、平均値が μ、標準偏差が σ の正規分布。
で、それぞれチャート作ってみました。
 
 
追記
 
JFreeChart 1.0.12 では Function2D から XYSeries を直接生成できませんが、DatasetUtilities#sampleFunction2D() メソッドで返される XYDataset が XYSeriesCollection オブジェクトなので、XYSeriesCollection の API を使って
 
XYSeriesCollection dataset = (XYSeriesCollection)DatasetUtilities.sampleFunction2D(...)
XYSeries series = dataset.getSeries(0)
とすれば XYSeries オブジェクトを取得することができます。

0 件のコメント:

コメントを投稿