<< (newer post) (older post) >>     

Plots/GR: グラフ package のおすすめ

Julia にはグラフを描くためのデフォルトの仕組みは(いまのところ?)無く、自分の好きな Package を選んで使ってね、というのが現状だ. そういう Package の有名ドコロの名前を挙げると、

  • Gadfly ゴージャスだが、遅くない?
  • Gaston gnuplot を使う. 軽くて速いけど、メンテが止まっているので、普通のユーザには使いにくいなあ.
  • GLVisualize 3D 専用の可視化ツール、というところかな.
  • GR GR framework を使う.Plots のバックエンドとして、本稿のお勧め.
  • PGFPlots LaTeX の pgfplots package を使う. 大変理論的にグラフを描けるが、作業はちょっと辛いかも?
  • PlotlyJS Plotly のようなグラフを描ける.Plotly のアカウントは不要のようだ.
  • Plots 他のツールをバックエンドとした、フロントエンド.お勧め.
  • PyPlot Python の matplotlib を使う.広く使われてるね.
  • Winston いろんなグラフが描けるけど、2D 専用だな.

という感じかな. で、お勧めは、今のところは

フロントエンド バックエンド
Plots GR

の組み合わせかな. これは、convert (ImageMagic) とか ffmpeg コマンドが OS で使えれば、データを動画にしてその場で見ることができるなど、なかなか優れものの可視化/グラフツールと言えよう.


インストール

さて、とりあえずのインストールは、Plots/Installation を見ればそのまんまだけど、まず Plots

Pkg.add("Plots")

としてインストール. その後、

Pkg.add("GR")

として GR もインストール. その後、

using Plots

として Plots を起動してから、

gr()

とすると、バックエンドに GR を指定できてあとは plot 関数を使ってグラフが描けるはずだ.


使ってみる: 二次元グラフ

カーネルを立ち上げてから Plots パッケージをまだ読み込んでいない場合は、

using Plots
gr()

として読み込んでおこう.

さて、例えば

plot(randn(100,3))

とすると、jupyter 上に aa という感じのグラフが表示されるし、データの各点にマーカーを打ちたければ marker オプションを指定して

plot(randn(100,3), marker=:circle)

などとすれば aa という感じに、データの各点に●でマーカーが打たれる.

また、そもそも線グラフではなく、点表示でと希望するならば seriestype オプションを変更して

plot(randn(100,3), st=:scatter)

とすれば aa という感じで点表示のグラフが表示される.


使ってみる: 三次元グラフ

カーネルを立ち上げてから Plots パッケージをまだ読み込んでいない場合は、

using Plots
gr()

として読み込んでおこう.

2次元同様に 3次元のグラフも簡単で、同じく plot を使えばいい.例えば

N = 200
d = 8π/N
x = [d*n*cos(d*n) for n in 0:N]
y = [d*n*sin(d*n) for n in 0:N]
z = 0.0:N
plot(x,y,z,marker=:circle)

とすると aa という感じの3次元グラフが表示される.

また、3次元の面のグラフを描きたければ plotseriestype オプションに :surface を与えて、

f(x,y) = (3x + y^2) * abs(sin(x) + cos(y))

x = 0:0.1:20
y = 0:0.1:10
z = [f(i,j) for i in x, j in y]' # この転置を忘れるとデータが矛盾し、グラフが変になるので要注意.

plot(x,y,z, st=:surface)

などとすると aa という感じの3次元グラフが表示される.

白黒のワイヤーフレームが良ければ、seriestype オプションを :wireframe にして

plot(x,y,z, st=:wireframe)

とすれば aa という感じの3次元グラフが表示される. ただし、これらのグラフは svg で処理されるため、ワイヤーフレーム表示は jupyter にとって大変に負荷が大きい. プロット点数を少なめにしておくなどして、配慮しておこう.

ちなみに、seriestype オプション無しで上の plot

plot(x,y,z)

として行うと、 aa という感じの等高線グラフになる.まあ最初はこれでいいんじゃねーの?


蛇足: gnuplot だと…

なお蛇足だが、こうした「面」の3次元グラフは、マウスで掴んで回せる分だけ、gnuplot で表示したほうが見易いし動作も軽いので、素直に gnuplot を使うことをおすすめする.まあ適材適所、ということだね. 具体的には、以前紹介したやり方で、

so,si,pr = readandwrite(`gnuplot.exe`)

println(si, "set hidden3d")
println(si, "set pm3d")

println(si, "set isosamples 50")
println(si, "set xrange [0:20]")
println(si, "set yrange [0:10]")

println(si, "f(x,y) = (3*x + y*y) * abs(sin(x) + cos(y))")

println(si, "splot(f(x,y))")

とでもすれば, gnuplot が aa という感じのグラフを出してくる.これは関数を指示して書かせているけど、データでも同じく簡単だ(前回示した). このグラフはマウスで掴んでグリグリ回していろんな角度から見られるので、大変便利.


ソースのトラブルを直そう

注: 2016.11 現在はこのトラブル直っているのでこの節は無視して良い.

そこで、ソースを追っかけてみて、とりあえずその問題点が判明して対策を用意できたと思うので書いておく.なお、OS は Windows を想定している.

問題点 1.
Package の GR/deps/gr 以下にある dll ファイルが Julia 実行環境から見えてないため、plot 関数を使おうとした時にコケる.
その対策
例えば、この Package の GR/deps/gr ディレクトリを PATH に入れてしまうという手がある.乱暴だけど.他にも、これらの dll ファイルを PATH の通ったディレクトリなどにコピーする手もあるけど、これだと、GR がアップデートするたびに dll ファイルを手動でコピーしないといけない.まあ筋論でいうなら、Pkg.add("GR") する前にそもそも GR を別途インストールしておくというのが一番まっとうで、そうしておくのも良さそう.
問題点 2.
バックエンドが「気を利かせて」作業用ファイル名を綺麗に直してしまう.もう少し詳しく書くと、Plots は二重拡張子があってもそのまま扱うという素直な実装なんだが、バックエンド GR の下請けの GKS が二重以上の拡張子があると「気を利かせて」途中の拡張子を削ってしまうらしい.そのため、Plots が GR/GKS の結果を plot しようとした時にファイルが見つからなくてコケる.
その対策
Package の Plots/src/backends/gr.jl の 967 行目を、ファイルが二重拡張子にならないように、
filepath = replace(tempname(),".tmp","") * "." * $fmt
などと修正する.

とりあえず、この対策で Plots/GR が動くようになるだろう.

     << (newer post) (older post) >>