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
- 正規分布関数。 wikipedia:正規分布参照。 new NormalDistribution2D(μ, σ) は、平均値が μ、標準偏差が σ の正規分布。
で、それぞれチャート作ってみました。
LineFunction2D
PowerFunction2D
NormalDistribution2D
追記
JFreeChart 1.0.12 では Function2D から XYSeries を直接生成できませんが、DatasetUtilities#sampleFunction2D() メソッドで返される XYDataset が XYSeriesCollection オブジェクトなので、XYSeriesCollection の API を使って
XYSeriesCollection dataset = (XYSeriesCollection)DatasetUtilities.sampleFunction2D(...) XYSeries series = dataset.getSeries(0)
とすれば XYSeries オブジェクトを取得することができます。
- 作者: Dierk Konig,Andrew Glover,Paul King,Guillaume Laforge,Jon Skeet,杉浦孝,櫻井正樹,須江信洋,関谷和愛,佐野徹郎,寺沢尚史
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2008/09/27
- メディア: 単行本(ソフトカバー)
- 購入: 5人 クリック: 146回
- この商品を含むブログ (121件) を見る
関数とはなんだろう―三角関数から複素関数・超関数まで (ブルーバックス)
- 作者: 山根英司
- 出版社/メーカー: 講談社
- 発売日: 2008/07/23
- メディア: 新書
- 購入: 2人 クリック: 128回
- この商品を含むブログ (7件) を見る
*1:sampleFunction2D() メソッドの名前は 「Function2D をサンプリングする」という意味なので当然といえば当然ですが。