Help us understand the problem. What is going on with this article?

Incanterで3D円グラフを描く & マルチメソッドの拡張

More than 5 years have passed since last update.

3D円グラフは、使うと死が待っています。

範囲を選択_015.png

その錯視が、どんなものか分からないと殺せるものも殺せないので、3D円グラフを描いてみることにします。

IncanterはClojureの統計解析ライブラリですが、肝心の3D円グラフは描けません。
ですが、中で使われているJFreeChartは、3D円グラフReadyです。(サイトのロゴが3D円グラフなのは皮肉なものです)

これを拡張します。通常の円グラフは以下のように書けます。

(view (pie-chart ["a" "b" "c"] [10 20 30]))

なので同じ感じで、pie-chart-3d関数を追加します。

ソースはpie-chartをまるっとコピーし、ChartFactoryでChartオブジェクトを作るところだけ、createPieChartからcreatePieChart3Dに書き換えます。

https
(ChartFactory/createPieChart3D
                  title
                  dataset
                  legend?
                  false
                  false)

これで3D円グラフのチャートが生成されます。

(view (pie-chart-3d ["a" "b" "c"] [10 20 30]))

IncanterではSwingを使ってグラフを表示するのにview関数を、画像ファイルに出力するのにsave関数をそれぞれ使います。せっかくの3D円グラフなので、錯視が如何ほどのものか、その3Dの視点をグリグリ動かしてみたいですよね!
そこで、view関数を再定義してみます。

https
(defmethod view org.jfree.chart.JFreeChart
  ([chart & options]
    (let [opts (when options (apply assoc {} options))
          window-title (or (:window-title opts) "Incanter Plot")
          width (or (:width opts) 500)
          height (or (:height opts) 400)
          frame (ChartFrame. window-title chart)]
      (doto frame
        (.setSize width height)
        (.setVisible true))
      frame)))

viewの定義はマルチメソッドになっていて、JFreeChartクラスのインスタンスだったらこのview関数で処理されます。JFreeChartのオブジェクト構成は、グラフの種類はJFreeChartのオブジェクトがもつPlotで区別されます。グラフの種類によらずChartFactoryで生成されるオブジェクトは、すべてJFreeChartクラスのインスタンスになります。したがって、このようにJFreeChartクラスでディスパッチされると"3D円グラフだけ特別な処理をする"ということができないのです。

この挙動を変えるには、次のようにします。

https
(when-let [original-view-fn (get-method view org.jfree.chart.JFreeChart)]
  (defmethod view org.jfree.chart.JFreeChart [chart & options]
    (let [view (apply original-view-fn chart options)]
      (when (= (type (.getPlot chart)) org.jfree.chart.plot.PiePlot3D)
        (pie-slider view))
      view)))

基本的にはdefmethodで再定義するのですが、元のメソッドをget-method関数で取り出しておくのがポイントです。そしてPlotがPiePlot3Dのときだけ、右側にスライダーをつけるようにしています。

スライダー付き3D円グラフ

同様にsaveも再定義して、3D円グラフでファイル拡張子がGIFのときだけ、アニメーションGIFを出力するようにしました。ぜひお使いください。

3D円グラフアニメ


incanter-charts-3d
https://github.com/kawasima/incanter-charts-3d

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした