JFreeChart で関数をプロットする方法を紹介。
チャートを生成する大雑把な手順は
Function2D オブジェクトを生成する
Dataset オブジェクトを生成する
JFreeChart オブジェクトを生成して表示する
です。
Dataset オブジェクトを生成する
JFreeChart オブジェクトを生成して表示する
です。
Function2D インターフェース
JFreeChart で関数を表すには、 org.jfree.data.function.Function2D インターフェースを用います。 このインターフェースは引数から値を計算して返す getValue() メソッドのみ定義されています:
package org.jfree.data.function;
public interface Function2D{
double getValue(double x);
}
このインターフェースを実装するクラスであれば、以下で見る方法でチャートを表示することができます:
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;
}
}
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つしかないインターフェースはクロージャを用いて簡単にインスタンスを生成できます:
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 オブジェクトの生成
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"
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。
この結果返される 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() などでチャートを生成すると、跳び跳びのグラフが表示されます。
ちなみに、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(μ, σ) は、平均値が μ、標準偏差が σ の正規分布。
で、それぞれチャート作ってみました。
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 オブジェクトを取得することができます。
XYSeries series = dataset.getSeries(0)
とすれば XYSeries オブジェクトを取得することができます。
0 件のコメント:
コメントを投稿