注意
-
Juno のメンテナーが VSCode に乗り移る動きがあります.今後は VSCode を使っていくと良いと思います.
本日は
Julia のIDE Juno を使って快適なJuliaとの生活をする手引き(前半)
の続きです.前回はJulia,Atom,Junoの導入と最低限の動作の確認をしました.
ここでは可視化を行うパッケージを例に簡単な描画の結果の閲覧をする方法,デバッガを動かす方法をノベマス.
可視化しよう
グラフの描画ここでは GR バックエンドの Plots.jl を例にグラフを描画する例を見てみましょう.
Atom上でファイルに書いて実行してもいいですしREPLで実行するでも良いです.ここではAtomのREPLを立ち上げて実行をしています.そうすると描画の結果がPlots
という領域に表示されます.これはエディタの左端に見えるヒストグラムのようなアイコンをクリックすることでも閲覧できます.
plots([sin,cos],-pi,pi)
は sin
, cos
を指定した範囲で描画するというものです.人間は欲が出るものでこの色を赤にしたい,青にしたいとか色々思うところはあると思いますが,それはそれで大変なので公式ドキュメントを眺めてみてください.
画像も表示
画像も見たいでしょう.
using TestImages
using Plots
cameraman=testimage("cameraman");
lena=testimage("lena");
p1 = plot(cameraman);
p2 = plot(lena);
plot(p1, p2, layout = (1, 2), size = (600, 300))
ここで,plot
という関数がいっぱい出てきますが Julia の multiple dispatch によって入力される型によって method が変わっています.とりあえず plot
という関数の名前だけ覚えておいて描画したいオブジェクトを入れ込みたいものをポコポコ plot
に突っ込ませればいいわけです.Julia における multiple dispatch のコンセプトについては公式ドキュメント Methods の冒頭の段落にエッセンスが詰まっています.
なぜ ImageView を使わないのか
画像処理のライブラリ Images.jl と関連して ImageView.jl というJuliaのパッケージがあります.
名前の通り画像を表示するものですが,これの依存となる Cairo.jl のビルドが各方面のOSでことごとく失敗するIssueが出てます.Macも例外ではありません.一応回避策はある みたいですが,私のiMacでは回避できませんでした.システムの brew と Juliaの Homebrew.jl が管理している brew の両方をマネージしてビルドを成功させないといけないのはちょっと辛いです.現時点では Plots.jlの plot
を用いるか PyCall.jl 経由で慣れ親しんでいる Python の画像処理ライブラリを呼び出すという選択が良いでしょう.
もう少し華やかな例
Lorenz Attractor のコードをそのままREPLにペーストします.そうすると Plots のパネルにぐるぐると描画される様子が見られます.必要に応じて brew install ffmpeg
などでgifを作るためのパッケージが必要になります.
あぁ何もわからん
using TestImages
using Plots
cameraman = testimage("cameraman");
lena = testimage("lena");
p1 = plot(cameraman);
p2 = plot(lena);
plot(p1, p2, layout = (1, 2), size = (600, 300))
今回は簡単で名前から testimage
は TestImages.jl
で定義されている関数だろうというのは想像つきます. using TestImages
することで スコープに testimages
なる識別子が導入されます.Juliaはどこに何があるかは知っている,知っていないのはお前だけな状態から救うのにJunoの力を借りましょう.
Help mode で Julia に救いの手を求める
公式のドキュメントにもあるように
Help mode を使います.ちゃんとした?ライブラリであれば docstring が書いてあるのでそれを手掛かりに調べるのも良いでしょう.
julia> #?キーを入力
help?> #切り替わる
help?> testimage
search: testimage TestImages
testimage(filename, [ops...])
load test image that partially matches filename, the first match is used if there're more than one. If
ops is specified, it will be passed to load function. use TestImages.remotefiles to get a full list of
available images.
Example
≡≡≡≡≡≡≡≡≡
julia> using TestImages
julia> testimage("cameraman.tif")
julia> testimage("cameraman")
julia> testimage("c")
julia> # この方法でも良い
julia> @doc testimage
@which
マクロを用いる
手掛かりを知るという意味では @which
マクロを使う方法もありますね.
help?> @which
@which
Applied to a function or macro call, it evaluates the arguments to the specified call, and returns the
Method object for the method that would be called for those arguments. Applied to a variable, it returns
the module in which the variable was bound. It calls out to the which function.
julia> @which testimage
TestImages
- https://juliadocs.github.io/Julia-Cheat-Sheet/ も見ると良いでしょう.
Juno「え,私を使ってよ・・・」
JunoのDocumentationを検索する機能を使ってみましょう.○の中に i があるアイコンをクリックしてそこに testimages
とか plot
などを入れてみましょう.
ラムダは関数を,ダンボールはパッケージを表しているみたいですね.testimage
をクリックすると対応するソースコードにジャンプします(下図参照).
何かみたことがある文字が出ていますが,Help mode での出力結果は関数に紐づいている docstring だったことがわかります.
マウス「右クリック...」
plot
はどうでしょう? multiple dispatch で同じ名前でも機能が違うと戸惑う人もいるのではないでしょうか?
とりあえず,調べたい対象に右クリックをして Julia-Client -> Go to Definition
することで所望の結果にアクセスする手掛かりを見つけることができます.
うーんどれかわからんけれど,型を合わせるならコレかな?という雰囲気で探すことはできますね.
走らせて確認したい.そんなあなたにデバッガ
plot(p1, p2, layout = (1, 2), size = (600, 300))
の行にブレークポイントを設定しましょう.ブレークポイントは行番号の隣をクリックすることで設定できます.赤いポチが見えれば成功です.外すときはそのポチを押せば元に戻ります.
REPL で次を実行します.
Juno.@enter plot(p1, p2, layout = (1, 2), size = (600, 300))
Junoの便利なところはソースで実行してもその名前がREPLでも使えるということです.(裏目にもなりますが)
このようにすると指定した式の評価とデバッガが起動し,虫マークのアイコンの領域が出現します.(下の図参照)
結論としては
function plot(plt1::Plot, plts_tail::Plot...; kw...)
plotattributes = KW(kw)
preprocessArgs!(plotattributes)
が呼び出されたことになります.自分で書いたソース以外の部分に深掘りして探ることができます.
ちなみに ...
がいっぱい出てきますが,splat operator というようです.実は Help mode で教えてくれる.
help?> ...
search:
...
The "splat" operator, ..., represents a sequence of arguments. ...
can be used in function definitions, to indicate that the function
accepts an arbitrary number of arguments. ... can also be used to
apply a function to a sequence of arguments.
Examples
≡≡≡≡≡≡≡≡≡≡
julia> add(xs...) = reduce(+, xs)
add (generic function with 1 method)
julia> add(1, 2, 3, 4, 5)
15
julia> add([1, 2, 3]...)
6
julia> add(7, 1:100..., 1000:1100...)
111107
お気持ち程度で Python の list などのデータ構造の前につける *
な存在だと思ってください(実際の挙動は違いますが)
条件を指定してブレークする
例えば下記のようなループが入る関数の中を見たいとします.ブレークポイントを置いておくとループが回るたびにブレークします.ループが一定回数などの特定の条件でブレークすることができれば便利ですよね?
function main()
for i in 1:10
j = i - 1
k = i + 1
@show i^2 + j^2 + k^2
end
end
そこで Debugger のパネルの中にある Breakpoints を見てみましょう.
上の画像の右下にあるYの字のアイコンを押します.
Condition の条件を記述して Confirm ボタンを押します.ブレークポイントは青色に変色します.
デバッガのDebug continue という早送りボタンを押すと確かに k
が6を満たす時にブレークする様子がわかります.ループが100以上の時に不具合が起きる・・・みたいな時に調べることができるのは便利ですね.
おまけ
自分でUI位置を変更したい.
julia-client の中の設定で選ぶことができます.
以上で後半戦終了ですお疲れ様でした.
まとめ
前半ではJunoの導入と簡単な動かし方を示しました.
後半戦ではより実践的に可視化パッケージを使って結果をAtom内のUIに埋め込むことをしました.
ソースコードを読む時にJuliaのドキュメントを見る方法,Go to definition の方法を学びました.
さらに深く進む時にデバッガを使うと実行時のデータの処理がどのようにして行われるかを知ることができました.