グラフを描くには

Julia でグラフを描くツール(package)はたくさんあるが、まあ、ほぼデフォルトでのおすすめが “Plots” package だ. juliabox では既にインストールされているので、使いたいセッション中で一回だけ

1
using Plots

とすればよい.その後、そのセッション内では自由に(後述の) plot() 命令が使える.

注: 私物PC のような環境の場合は、この package を(その PC について一回だけでよい)インストールしておかないといけない. そうした場合のインストールは簡単で、

1
2
using Pkg
Pkg.add("Plots")

とするだけでよい.

というわけで、まずはこの「使うよ宣言」(using Plots)をしておこう(私物 PC の人は、インストールを先にやっておこう).

そして、Julia で基本的なグラフを描くには、plot 命令を使えば良い. おおよそ、

  • ベクトルを plot に渡すと、普通の 2次元グラフを描いてくれる
  • 行列を contour に渡すと(3次元データの)等高線グラフを、
  • 行列を heatmap に渡すと(3次元データの)色付けによる z軸上方向から見たグラフを、
  • 行列を wireframe に渡すと(3次元データの)立体ワイヤーフレームグラフを、
  • 行列を surface に渡すと(3次元データの)立体のきれいなグラフを、描いてくれる.

tips: 実は, contour(A)plot(A, st = :contour) の省略形だ.heatmap 等も同様だ.

例えば、まず、データぽいベクトルを作ってみる.

1
v = [ n^2 for n in -2:0.1:2 ]  # -2から2まで0.1おきの数字を二乗して並べたベクトル

41-elementArray{Float64,1}: 4.0 3.61 3.24 2.8899999999999997 2.5600000000000005 2.25 1.9599999999999997 1.6900000000000002 1.44 1.2100000000000002 1.0 0.81 0.6400000000000001 ⋮ 0.81 1.0 1.2100000000000002 1.44 1.6900000000000002 1.9599999999999997 2.25 2.5600000000000005 2.8899999999999997 3.24 3.61 4.0

このベクトル vplot 命令に渡してみよう

1
plot(v)  # plot 命令も、そのセッションで初めて動くときだけは遅いよ.すこし待とう.

無事にグラフが描かれることがわかってもらえると思う.
基本はこのノリで、データをベクトル形式に突っ込んでそれを plot に渡せば良い.

グラフの各点にマーカーがあったほうが良いな、という場合は例えば次のようにすれば良い.

1
plot(v, marker = :auto)

ちなみにこうした情報は、Julia 自身のもつ内部マニュアルでひいていくことができる(英語だけどね). 今回は次のような感じでわかる.

1
?plot  # plot 命令について、尋ねてみる

The main plot command. Use plot to create a new plot object, and plot! to add to an existing one: plot(args…; kw…) # creates a new plot window, and sets it to be the current plot!(args…; kw…) # adds to the current plot!(plotobj, args…; kw…) # adds to the plot plotobj There are lots of ways to pass in data, and lots of keyword arguments… just try it and it will likely work as expected. When you pass in matrices, it splits by columns. To see the list of available attributes, use the plotattr([attr]) function, where attr is the symbol :Series:, :Subplot:, :Plot or :Axis. Pass any attribute to plotattr as a String to look up its docstring; e.g. plotattr(“seriestype”).

1
plotattr(:Series)  # とりあえず、最初にでてきたキーワード :Series について、上に書かれた通りに調べてみる.

Defined Series attributes are: arrow, bar_edges, bar_position, bar_width, bins, contour_labels, contours, fill_z, fillalpha, fillcolor, fillrange, group, hover, label, levels, line_z, linealpha, linecolor, linestyle, linewidth, marker_z, markeralpha, markercolor, markershape, markersize, markerstrokealpha, markerstrokecolor, markerstrokestyle, markerstrokewidth, match_dimensions, normalize, orientation, primary, quiver, ribbon, series_annotations, seriesalpha, seriescolor, seriestype, smooth, stride, subplot, weights, x, xerror, y, yerror, z

1
plotattr("markershape")  # マーカーの形状についてなにかわかりそうだ

markershape {Symbol, Shape, or AbstractVector} markershapes, shape Choose from Symbol[:none, :auto, :circle, :rect, :star5, :diamond, :hexagon, :cross, :xcross, :utriangle, :dtriangle, :rtriangle, :ltriangle, :pentagon, :heptagon, :octagon, :star4, :star6, :star7, :star8, :vline, :hline, :+, :x]. Series attribute, default: none

これによると、マーカーの形状を自分で指定することも簡単だ.例えば六角形でやってみると…

1
plot(v, marker = :hexagon)

よく見ると確かに六角形がマーカーになっている.

次に、3次元グラフにもチャレンジしてみよう

1
A = [ x^2 + y^2 for x in -1:0.1:1, y in -1:0.2:1 ]  # x^2 + y^2 の値に相当する行列を作る

21×11 Array{Float64,2}: 2.0 1.64 1.36 1.16 1.04 1.0 1.04 1.16 1.36 1.64 2.0 1.81 1.45 1.17 0.97 0.85 0.81 0.85 0.97 1.17 1.45 1.81 1.64 1.28 1.0 0.8 0.68 0.64 0.68 0.8 1.0 1.28 1.64 1.49 1.13 0.85 0.65 0.53 0.49 0.53 0.65 0.85 1.13 1.49 1.36 1.0 0.72 0.52 0.4 0.36 0.4 0.52 0.72 1.0 1.36 1.25 0.89 0.61 0.41 0.29 0.25 0.29 0.41 0.61 0.89 1.25 1.16 0.8 0.52 0.32 0.2 0.16 0.2 0.32 0.52 0.8 1.16 1.09 0.73 0.45 0.25 0.13 0.09 0.13 0.25 0.45 0.73 1.09 1.04 0.68 0.4 0.2 0.08 0.04 0.08 0.2 0.4 0.68 1.04 1.01 0.65 0.37 0.17 0.05 0.01 0.05 0.17 0.37 0.65 1.01 1.0 0.64 0.36 0.16 0.04 0.0 0.04 0.16 0.36 0.64 1.0 1.01 0.65 0.37 0.17 0.05 0.01 0.05 0.17 0.37 0.65 1.01 1.04 0.68 0.4 0.2 0.08 0.04 0.08 0.2 0.4 0.68 1.04 1.09 0.73 0.45 0.25 0.13 0.09 0.13 0.25 0.45 0.73 1.09 1.16 0.8 0.52 0.32 0.2 0.16 0.2 0.32 0.52 0.8 1.16 1.25 0.89 0.61 0.41 0.29 0.25 0.29 0.41 0.61 0.89 1.25 1.36 1.0 0.72 0.52 0.4 0.36 0.4 0.52 0.72 1.0 1.36 1.49 1.13 0.85 0.65 0.53 0.49 0.53 0.65 0.85 1.13 1.49 1.64 1.28 1.0 0.8 0.68 0.64 0.68 0.8 1.0 1.28 1.64 1.81 1.45 1.17 0.97 0.85 0.81 0.85 0.97 1.17 1.45 1.81 2.0 1.64 1.36 1.16 1.04 1.0 1.04 1.16 1.36 1.64 2.0

さあ、プロットしてみよう.最初は contour (等高線表示になる)だ.

1
contour(A)

tips: ちなみに、plot に行列 A だけを渡すと、(この場合は)「縦ベクトル11個のデータを一度に渡した」と解釈され、11個のグラフを同時描画する. これはこれで使えるテクニックなので覚えておこう.

1
plot(A)

次は heatmap だ.

1
heatmap(A)

heatmap

まあどちらかというと、contour に fill オプションをつけたほうが良さそうだ.

1
contour(A, fill = true )

次は wireframe だ.

web browser への負荷は高いが…

1
wireframe(A)

wireframe

最後は sufrace だ.

1
surface(A)

surface

tips: wireframesurface などの 3次元プロットでは、camera = (平面角, 高さ角) というオプションをつけると、その位置にカメラを置いた表示にしてくれる. デフォルトは camera = (30,30) だ. ちなみに、平面角も高さ角も (なぜか) 0 から90までに制限されているようだ. 詳しくは plotattr("camera") とすると簡単なマニュアルが出るので読んでみよう.

ちなみに、下の画像はこの camera オプションを使ってみた例だ. デフォルトのものと、グラフを眺めている位置が異なるのが分かるだろう.

1
wireframe(A, camera=(22,58))

wireframe

パラメータを変えて試行錯誤するときに便利なパッケージ Interact を使って、グラフを動かそう

package Interact についてはまた詳しくやるとして、ここでは以下のようにしてみよう.

juliabox にはすでにこのパッケージがインストールされているので、使うときにそのセッションで一回だけ、Interact の使用宣言をすればよい.

1
using Interact

それから、次のようにしてみよう. ちなみに、@manipulate が Interact が提供している命令で、ここで指定したパラメータが画面に「バー」となって操作できるように現れる. バーを掴んで動かしてみよう.

1
2
3
@manipulate for θ in 0:2:90, h in 0:2:90
  wireframe(A, camera=(θ,h))
end

bars

wireframe

簡易アニメーション

本格的なものについてはまた学ぶとして、上の camera オプションに絡めて、簡単なアニメーションをその場で作る方法も書いておこう. これは上の @manipulate にそっくりの使い方で、下記の例をやってみればわかるだろう.

1
2
3
@gif for θ in 0:1:120
    wireframe(A, camera=(θ,30))
end

とすると、

┌ Info: Saved animation to │ fn = /mnt/juliabox/tmp.gif └ @ Plots /home/jrun/.julia/packages/Plots/UQI78/src/animation.jl:90

と出力されて、”tmp.gif” という名前でアニメーション gif ファイルが作られたことがわかる. そこで、web browser でさきほどのファイラー画面に行き、このファイルがないか見てみよう. 見つけたら、あとはそのファイルを例えばクリックするだけで、browser がその動画を見せてくれるだろう.

gif-sample