13. 科学技術計算用言語 Julia

juliia web

Julia とは何か

ここで紹介する Julia とは、MIT とか NYU あたりの人たちが開発中の,2012年に公開が始まった,科学技術計算の専用言語のこと. 本家 web にマニュアルやらチュートリアルやら動画やら、大変多くの様々な資料があるので、困ったらまずはここをみると良い.

そしてその言語の能力であるが、 開発者らが欲張りだと自認するだけあって,後発の強みも活かして,

  1. 科学技術計算に便利な文法になっている

  2. 科学技術計算に便利なコマンドやライブラリが最初からある

  3. *計算が速い
    注: 実行時間は(JIT コンパイルにかかる時間は除いて)ほんとに高速で,C や Fortran とほぼ同等だ. Julia Micro-Benchmark に他のコンピュータ言語等での計算速度を比較したベンチマークのグラフが載っているので見てみよう.

  4. 言語設計が近代的なので,プログラミングが随分楽

という、大変多くの利点がある言語になっている.これからが楽しみな言語だ.

今のところ?JIT compile, つまり「実行時にコンパイルして動かすスタイル」をとっているので,使い勝手的にはインタプリタと言える プログラム開発中や,いろいろ試しながら動かすにも,これは便利.

よって,「たいへん気楽に使える高速な科学技術計算言語」として使える. また,ライセンスはMIT ライセンスなので安心して無料で使えるし,ソースも全部公開されているので中身をいじりたければ自由にいじれる.


ぜひ、この言語を自分のものとして、便利に使えるようになってもらいたい.

知っておくと混乱しないで済む?基本知識

少し、大雑把なことを書いておこう.

  1. Julia は(上に書いたように) JIT コンパイラがその場でこれから使う部分だけをコンパイルして動かす仕組み.
    つまり,プログラムを「本当に」実行するマシン上には Julia 環境(Julia カーネル)がインストールされている必要がある.

  2. プログラムの関数やルーチンをそのカーネルセッションで「初めて動かすとき」は JIT コンパイルにかかる時間が余計にかかる.
    「ちょっと 1回だけ触ってみた」という使い方だとこのせいで「Julia って遅くね?」と誤解するかもしれないので注意しよう.

  3. Julia プログラムを動かす「カーネル」と,人間用インターフェイスは分離できるし,違うコンピュータに置くこともできる.
    よって「使い勝手の良いインターフェイス」を自分で選ぶことが推奨されるし,インターフェイスは手元の PC で動かしつつ,実際にプログラムが動く環境は計算用の大きなサーバに置くということもできる.

  4. 緩いデフォルト的な存在1はあるけれども,グラフを描くライブラリや文法は自由に選べる.
  1. インターフェイスとしては,以下の様なものが有名だ.好きなものが選べるぞ.


web browser で操作するインターフェイス. セル入力して送信した内容をそのたびに動作する形で,試行錯誤するのにぴったり.

あと,Julia だけではなくて,Python や R でも同じインターフェイス jupyter が使えるぞ2


インターフェイスとして Julia との関係は上図の通り. わかりやすいし,資料も多くておすすめ. これを使うと,Mathematica や Matlab のような見た目と使い勝手になる.
今回はこれを用いよう



2020年3月の ver.0.2.0 あたりが初リリースかな.それからまだ2年ぐらいしかたっていないかなり新しいインターフェイス. jupyter 同様,web browser で操作するものだが,セッション中の全入力が同期(一箇所の変更がただちにセッション中全ての入力と結果に反映される = 計算し直しが起きる,ということ)して動作する. わかりやすさはピカイチかな.

MIT の授業などで用いられているようだ. 気になる人は MIT の授業動画 などを見てみるといいだろう.

規模が大きい処理には向かないだろうが,比較的小さな実験を繰り返すとか,インタラクティブな操作をスムーズに行いたい時などは特に威力を発揮するだろう.


Julia for VSCode
VS code エディタのプラグインと Julia のパッケージをうまく使った IDE 環境. かつての,Atom エディタ上で動く Julia 用の統合開発環境だった Juno の後継環境のようだ3

大人気の VS code で使えるし,文法に沿ったいろいろなアシスト機能があって大変便利のようだ. ただし,トラブルが起きた時は Julia package, VS code, このプラグインの 3者のどこに原因があるかを調べねばならないため解決はやや面倒かもしれないね.


その他にも以下のようなインターフェイスもある.

  • 文字端末ソフトで直接対話する REPL

    Windows だと Powershell で,Unix 系だと shell から Julia を立ち上げて,いわゆる「黒い画面」で操作するもので, マニュアルなんかでは read-eval-print loop の略で REPL と呼ばれている.
    悪くない.悪くないが,カーネルが落ちるとそれまでのやりとりも画面から消えてしまうので,長時間扱うならやっぱインターフェイスは別にしておくといいかも.
    ちなみに,REPL でもグラフや画像の表示は思ったよりきちんとできる.画像がぽこっと別ウィンドウや web browser 呼び出しで出てくる様子はちょっとかわいいので一度試してみるといいかも.

  • Emacs での Julia 環境

    julia-mode 用の elisp (syntax highlight4 も行ってくれるぞ)や Emacs で動く統合開発環境 ESS (Emacs Speaks Statistics) などが古参の定番かな.

    あと,Julia の文法対応をしてくれる LanguageServer と組み合わせて使う eglot なんかは個人的にオススメだ.
  • Julia-vim

    vim の julia-mode らしい. vi使いは調べておくと良さそうだね.

それぞれの学習環境での状況

今回は Julia およびその web インターフェイス jupyter が使えないといけない. 詳細は下記に記載したが,なるべく自分の PC/Mac を用いるのが良いだろう.

環境 状況
阪大情報教育システム
Windows10
Julia 1.7.2 がインストール済み.ただし情教は Julia の Package を追加していくと個人ファイル容量が大きくなりシステム起動に支障が出かねない仕組みなので利用には不向きかなあ(あと,pkg 用の環境変数が古くて有効でない…).
jupyter はなぜか julia 1.5.3 用の設定になっていることでもあり… 今回はこれを用いるのは諦めざるを得ないかな.
阪大情報教育システム
CentOS7
Julia がインストールされていない.今回はこれは用いることができないな.
各自PC CentOS7
obtained at OSBoxes
1. まず次のようにして Julia 本体をインストール.

sudo yum update
sudo reboot ← 念の為のリブート
sudo yum-config-manager --add-repo https://copr.fedorainfracloud.org/coprs/nalimilan/julia/repo/epel-7/nalimilan-julia-epel-7.repo
sudo yum install julia

おそらく Julia ver.1.6.5 あたりがインストールされるだろう.ちょっと古いが,まあ使えなくはないかな.

2. 表の下の
jupyter インストール
の作業を行おう.

これで OK だ.今回はこれを用いても良い.
各自PC Ubuntu22.04
obtained at OSBoxes
他,Linux 一般
1. (長いので表の下に書いたのだが)まず,表の下の
Julia インストール: Linux 一般(Ubuntu22.04など)に
の作業を行おう.

2. 表の下の
jupyter インストール
の作業を行おう.

これで OK だ.今回はこれを用いても良い.
各自PC Windows 1.Windows のアカウント名に
半角アルファベット, 半角数字, 半角ハイフン, 半角ピリオド, 半角アンダースコア
以外の文字を使っていないか確認する. これ以外の文字を使っていると上記の jupyter 環境が使えない のだ.
もしもこれらの文字をアカウント名の中で使っている人は,アカウント名をこの条件に沿う様に変えるか,この条件に沿ったアカウントを別に用意してそちらにログインし直し,下記の作業へ進もう.これらの文字をアカウント名の中に使っていない人は,そのまま次の作業へ進もう.

2. help for windowsを読もう.そして,ver.1.7.3(for 64bit windows)をダウンロードしてダブルクリックしよう. 素の Julia がインストールできる.

3. 下記の
jupyter インストール編
の作業を行おう.

これで OK だ.今回はこれを用いても良い.
各自PC Mac OS 1. まず Julia 1.7.3 for Macをダウンロードし,help に従ってインストールしよう.

2. 次に,表の下の jupyter インストール
の作業を行えば良い.今回はこれを用いても良い.
上のどの環境も使えない人の場合 数名であればこの授業用に使えるサーバ(サーバについて 宮武先生の実験数学1の解説 がある )が有るので, 授業時に教員に申請しよう.その場でアカウントを渡す.
また,クラウド上で julia が使える環境を提供している会社があり,そう高いものでないし(後述の CoCalc はアカデミック用途ならば年間 $34.83 で使える),無料プランもあるのでそうしたものを使うのもよいだろう.たとえば, CoCalc などが挙げられる.こうした環境を使ってみるのも良いだろう.



Julia インストール: Linux 一般(Ubuntu22.04など)に

インストール方法の概要 for linux を読むと,次のように「ファイルのダウンロード, 配置(どこでもよい) and 呼び出しのためのリンク」をすれば良い. 他の OS の場合は上の表を見よう.

1
2
3
4
5
6
7
8
9
sudo cd /usr/local/lib
# ↑ Julia 環境をここに置くと決めた場合.自分で考えて変えて良いぞ.

sudo wget https://julialang-s3.julialang.org/bin/linux/x64/1.7/julia-1.7.3-linux-x86_64.tar.gz
sudo tar zxvf julia-1.7.3-linux-x86_64.tar.gz
sudo rm julia-1.7.3-linux-x86_64.tar.gz

sudo ln -s /usr/local/lib/julia-1.7.3/bin/julia /usr/local/bin/julia
# ↑ path の部分はフルpath, つまり, / で始まるようにする.



jupyter インストール編

jupyter インストールにはいくつかの方法があるが,ここでは最も簡単で,かつ,OS に依存しない方法を紹介しよう. 次の手順で一回だけ作業を行えば良い.

1.まず,Julia を起動する.Julia がインストールされているならば,どの OS でもメニューのどこかに Julia があるはずなのでそれを使おう. すると,

といった感じの window が起動するだろう(これは julia の REPL インターフェイス). ただし,window の色は環境依存なのでそこは気にしないように.

2.この Julia の window 中で ] キーを押す. すると,"julia>" というプロンプトが "(v1.7) pkg>" という感じのプロンプトに変わるだろう. これは Julia のパッケージ管理モードに入ったことを意味する.

3.このパッケージ管理モードのまま,

1
add IJulia

と入力する(大文字小文字の区別があるので注意). これは jupyter を使うための "IJulia" というパッケージのインストール作業である. しばらくかかるので待とう.

4.上の作業が終わったら,backspace キーを押す.すると通常モードに戻り "julia>" というプロンプトに戻るはずだ. そうしてから,次の 2つのコマンドを Julia に実行させよう.

1
2
using IJulia
notebook()

すると上の2つ目のコマンド notebook() を実行した時に jupyter 関連のソフトウェア一式をインストールしてくれる. このときインストール方式等について尋ねてくるが,よくわからない場合は y キーを押しておけば良い.

しばらく待つと,作業が終わる. もしかしたら web browser が起動したりもするが,この段階ではいったんその web browser も閉じ,この julia 環境も終了させてしまおう. これで一応,Julia と jupyter が使えるようになったはずだ.

Julia & jupyter を起動/終了するには

起動の手順

Julia を jupyter インターフェイスで利用するには,基本的には

1.Julia を起動.
2.Julia の中で以下の2行を行う.

1
2
using IJulia
notebook()

だけで良い. こうするだけで web browser が呼び出され,そこに下のような jupyter インターフェイスが表れるはずだ(見えている細かい内容は環境によって異なる).

これは jupyter のホーム画面とでも言うべき画面で,様々なファイル操作等はここを経由して行う.

  web browser が「hogehoge ファイルへのアクセスが拒否されました」というエラーを表示してきちんと動作しない時がある. これは(2022年の今は)基本的に web browser の問題なので,異なる web browser をインストールしてそちらを「既定」設定してやり直そう.

たとえば今の Ubuntu22.04 だと firefox が既定だが,このトラブルに会う. その場合は, How to Install Google Chrome on Ubuntu 22.04 に従って,

1
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb

としてダウンロードするか,web browser で chrome のインストールファイル(同じファイルのはず)ダウンロードしよう. そして,

1
2
sudo dpkg -i google-chrome-stable_current_amd64.deb
# 当たり前だが,ダウンロードしたファイル名を指定するのだ.

として google chrome をインストールし,その後,

1
google-chrome

として chrome を起動して「既定」に設定しよう(初起動時にこの設定にするか尋ねてくれる).



さて,jupyter が無事に起動したら, 次に Julia カーネルと接続して Julia を実際に使う画面を起動する. それには,この画面で右上に小さく見えている   New ▼   というボタンを押して,

という感じのメニューを出現させ,ここで "Julia 1.7.3" という部分を選べば良い. すると

といった画面が起動する. ここで入手力を行うことで,Julia を使う,Julia プログラムを動かす,といったことができる.

終了の手順

実際の使い方はこのあとすぐ説明するとして,次にここから終了する手順を示しておこう.

まず,Julia を使っている画面の左上を見て,

上図の赤い丸がついている部分のアイコンを押し,念の為に現状をセーブしておく.

次に,その上の "File" という部分を押すとメニューが出るので,その一番下の "Close and Halt" を選ぶ.

次に,jupyter のホーム画面に移り, 右上の "Quit" ボタンを押す.これで jupyter インターフェイスが終了する. あとは Julia 環境を終了させれば良い.

ともかく試してみる

文法云々の堅い話はおいておいて、まあ、まずは触ってみよう.

  実習
インストール不要, 無料で Julia をすぐ使える JuliaBox が公開されている
へ飛ぼう.書いてあることの半分ぐらいが今回の貴殿らの環境に合致するだろうから,そうした部分について、jupyter の操作の練習を兼ねてごく簡単に Julia を触ってこよう.
(注: 上の web で言及されている JuliaBox というサービスは現在は廃止されている)

文法等のマニュアル、解説

日本語で書かれた解説が載っている M. Hiroi's Home Page: Julia Language Programming や、英語でよければ 本家のマニュアル あたりをみると詳細な文法の解説があるので、困ったらこれらを読もう.

また、できれば本を一冊買っておくと良い. おすすめは 書籍: Julia 1.0 Programming (2nd ed.) で、英語だけれども大変読み易い.

もう少し試してみる

実際に自分でプログラムを組む前に、もう少し試してみたほうが良いだろう. というわけで、下記の実習をやっておこう.

  実習

  1. 超入門
  2. 魔法の加速法

自分でやってみる

さて、次に、ごく簡単な問題に実際に Julia で取り組んでみるのが良いだろう. というわけで、次の

Collatz の予想(角谷の問題)

正の整数 $n$ に対して、次のような写像 $f$ を考える.

\begin{equation} f(n) = \left\{ \begin{array}{lcl} 3n + 1 & \mbox{     } & : n \mbox{ が奇数の場合} \newline n/2 & & : n \mbox{ が偶数の場合} \end{array} \right. \end{equation} このとき、任意の正の整数に対して、$f$ を複数回適用するといずれ必ず結果が 1 になる.

という、現在なお未解決の数学の予想がある. この問題を対象にして少しいろいろ練習してみよう.

まず最初は例を示そう.

上の写像 $f$ を関数としてプログラムする.

やり方はいろいろだ.例を示しておこう.

素朴な実装例

1
2
3
4
5
6
7
function f(n)
  if isodd(n)       # isodd は、中身が奇数かどうかを判定する
    return 3n+1     # Julia は定数係数と変数の間の積の記号を省略可能.
  else
    return div(n,2) # n/2 の結果は浮動小数なので、整数を返す div を使う.
  end
end

三項演算子を使ってシンプルに書いた例

1
2
3
function f(n)
  isodd(n) ? 3n+1 : div(n,2)
end

関数宣言もシンプルに書いた例

1
f(n) = isodd(n) ? 3n+1 : div(n,2)

  実習
自力で、もしくは上のように $f$ を実装して、$f(3)$ が 10 になること、$f(10)$ が 5 になることを、以下のように確認しておこう.

1
2
f(3)  # 結果は 10 のはず.
f(10) # 結果は 5 のはず.


$f$ を何回適用すると結果が 1 になるかをカウントする関数 count を作る

例を一つだけ示しておこう.しかし, なるべく例を見ないで、マニュアルを読むなどして自力で組んでみよう.

1
2
3
4
5
6
7
8
9
function count(n)
    m = n
    number = 0
    while m > 1
        m = f(m)
        number += 1
    end
    return number
end

  実習
自力で、もしくは上のように count を実装して、count(3) が 7 になること、count(17) が 12 になることを、以下のように確認しておこう.

1
2
count(3)  # 結果は 7 のはず.
count(17) # 結果は 12 のはず.


奇数 n = 3,5,7,... に対して、count(n) を求めてグラフを描く

  実習
これも例を示しておくが、なるべく自力で頑張ってみよう.

1.まず、count(n) の結果の配列を作る

1
y = [count(n) for n in 3:2:2001] # 1000個ほどデータを用意する.

2.適当なグラフ描画パッケージ(デフォルトは Plots だ)を使ってグラフを描く.まあ,ここでは Plots を使ってみよう.

1
2
3
4
using Plots # セッション中で一回宣言すれば良い.

plot(y, st = :scatter, leg = false )   
# st = :scatter は点描画,leg = false は legend表示なし,の指定.

すると、
collatz points
という感じの,なにか規則性があるような無いようなグラフが見て取れる. この規則性,数式にできる?


n を大きくしていくと,あたりまえだけど「大雑把には」count(n) の最大値が大きくなる傾向があるね

$i = 3,5,7,...,n$ での count(i) の最大値を v(n) とすると(式だと次のようになるね)

\begin{equation} v(n) = \max_{i \leq n} \{ \mbox{count}(i) \} \end{equation}

この挙動はどういうものだろうか.

すぐに数式で求められそうにはないので,プログラムで求めてグラフを描いてみるのが良さそうだ.

例えば次のような感じにできるだろう.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
N = 200001

n_sq = [ 3 ]

max_c = count(3)
v_sq = [ max_c ]

for i in 5:2:N
    global max_c, n_sq, v_sq
    
    v = count(i)
    if v > max_c
        max_c = v
        push!(n_sq, i)
        push!(v_sq, v)
    end
    
end

とすると,n_sq に最大値 $v(n)$ が更新されたときの $n$ のリストが,そして v_sq にはその $v(n)$ のリストが計算されて記録される. だから,グラフを描いてみるとこんな感じ.

1
2
plot(n_sq, v_sq, marker = :auto, leg = false)
# marker = :auto はマークを自動的に決める指定.

d

う~む,どうも $\log$ 関数に似ているような気もするので,適当に並べて描いてみて比べてみよう.

1
2
3
plot(n_sq, v_sq, marker = :auto, leg = false)
plot!(n_sq, 30 .* log.(n_sq) )
# plot! はグラフを重ね描く.

d

う~むむむむ… 似ているような似ていないような… もっと N を大きくすると様子がわかるかな?

N を大きくして,x 軸の対数をとってグラフにしてみよう.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
N = 10000001

n_sq = [ 3 ]

max_c = count(3)
v_sq = [ max_c ]

for i in 5:2:N
    global max_c, n_sq, v_sq
    
    v = count(i)
    if v > max_c
        max_c = v
        push!(n_sq, i)
        push!(v_sq, v)
    end
    
end

plot(n_sq, v_sq, marker = :auto, leg = false, xaxis = :log)

d

う~むむむむむむむむ… 直線に近いがちょっとだけ強い…?

両対数だとどうだろうか.

1
plot(n_sq, v_sq, marker = :auto, leg = false, xaxis = :log, yaxis = :log)

d

おお! なにか掴んだ気がするぞ! $n > 10^2$ ぐらいでの $v(n)$ をおおよその数式にしてみよう!(学生のみんなへの課題だね)

レポート

以下の課題について能う限り賢明な調査と考察を行い,
2022-AppliedMath7-Report-13
という題名をつけて e-mail にて教官宛にレポートとして提出せよ. なお,レポートを e-mail の代わりに TeX で作成した書面にて提出してもよい.

課題

  1. 上の内容を、一回自力でやり通してみよう. そして,最後のグラフの後に書いたように, $n > 10^2$ ぐらいでの $v(n)$ をおおよその数式の形で推測して,あらためてデータのグラフとその数式のグラフを同時に描いて比較してみよう.

  2. 「正 $n$ 角形の周長 $L(n)$ を定規で測ったデータ」をプログラム計算で擬似的に生成して5 、$n \rightarrow \infty$ で確かに $L(n) \rightarrow 2\pi r$ (ただし$r$ は正 $n$ 角形の外接円の半径相当)となることを数値データで確かめよう.

  3. 問2 のデータに対して、 魔法の加速法 で解説されている Aitken 加速法を適用したら収束先が「早い段階で」「より精密にわかるか」どうかを試して、その状況を報告しよう.さらに、多重に適用してみよう.



Appendix 1: Julia でグラフを描く

Julia でグラフを描くツール, ライブラリ(package)はたくさんあるが、現在デフォルト扱いになっているものが "Plots" package だ. 上で既に使っているが,これを紹介しておこう.

  英語だがマニュアル Plots document があるので,細かいことを知りたければ目を通すとよいだろう.

さて,この Plots package をインストール済みでなければ, Julia 環境で

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

とすればインストールできるのでそうしておこう. 大きめの Package なのでインストールにはやや時間がかかるが,まあ待とう.

いったんインストールしてしまえば,その後は

1
using Plots

とすればそのセッション中では Plots package が有効になり(後述の) plot 命令などが使える.

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

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

あたりを押さえておけば良い感じだろう.

プログラミングについて知っている人向けに言うと,Julia でベクトルといえば 1次元配列そのもののことで,行列は2次元配列そのものである.
上の contour(A)plot(A, st = :contour) の省略形だ.heatmap 等も同様.

さっそく,例えば三角関数のグラフを描いてみよう.

1
plot(sin)

そのセッションで初めて使う plot は実行まで少し時間がかかる.待とう.

とても簡単だね!!

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

1
2
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 に渡せば良い.

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

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
2
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
2
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)

ちなみに、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

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

詳しくは plotattr("camera") とすると簡単なマニュアルが出るので読んでみよう.

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

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

wireframe

plot したグラフを保存しよう

役に立つグラフが得られたならば保存しておきたい. plot したグラフの保存はいくつかの方法があるが,一番簡単な方法はグラフを描いた後,savefig コマンドを使う方法である. それを紹介しておこう.

例えば,適当な4次関数を以下のように描いたとしよう.

1
plot( x -> x^4 - 20*x^2 + 1 )

このグラフを画像ファイルに保存したければ,この後に,

1
2
3
4
5
6
plot!(size = (1200,800)) 
# 画像ファイルのサイズ指定.指定しない場合は 600x400 になる.

savefig("sample.png")
# これで sample.png という名前で png ファイルとして保存される.
# 拡張子で画像ファイルの種類が決まる.

などとすれば良い. jupyter のファイラー画面などから,確かに画像ファイルが保存されていることを確認しておこう.

savefig コマンドで出力できる画像ファイルの種類は描画 backend (実際に描画を行うライブラリ)の種類によって異なる. とくに設定を変えずに Plots を使っているデフォルトだと GR と呼ばれる backend が用いられ,pdf, png, ps, svg が出力可能だ. 詳しくは Plots マニュアルの Supported outpout file formats を見よう.

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

なかなか便利な package Interact をここで紹介しよう. 詳しくはまた解説する機会を設けるが,まずは簡単に,という感じだ.

この package のインストール方法は環境によって異なる. ここでは Julia + jupyter 環境の話をする.

Interact のGitHub はインストール方法については少し古い記述で今は有効ではないので, WebIO の GitHub を参考にすると良い. といっても初心者にはなにがなんだかというところだろうから,具体的には下記のようにすれば良い.

Interact package の Install方法:
Julia の REPL環境(黒い文字だけの環境) を起動して,下記のようにインストールする.
この作業は一回だけ行えば良い.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
]  # ← このキーを押すと,package 管理モードに入る.

add Interact
add WebIO
add Conda

Backspaceキー # ← backspace キーを押すと,通常モードに戻る

using WebIO
using Conda
Conda.pip_interop(true)
Conda.pip("install", "webio_jupyter_extension")

これでインストールは終了だ7

さて,話を戻そう. このようにして上記のインストールが済んだ状態で,Julia + jupyter 環境でこの package を読み込む.

1
using Interact

これでこのセッション中は Interact package が使えるわけだ. 試しに,グラフと関係ない次の簡単な例でこの Interact package の機能を味わってみよう.

1
2
3
@manipulate for x in 0:10
  x^2
end

さて,この3行を実行すると という感じの表示が出て,バーをマウスで掴んで動かすと変数 $x$ の値を変えられ,出力 $x^2$ の値もそれに応じて変わるはずだ.

このように,プログラムの中の変数/パラメータの数字をマウスで自在に変えられ,その結果をリアルタイムでみることができるのがこの @manipulate 命令のありがたい機能なのだ.

さて話をグラフ描画に戻して, 次の内容を実行してみよう(最初の2行はもう見たことがあるだろう)..

1
2
3
4
5
6
using Plots
A = [ x^2 + y^2 for x in -1:0.1:1, y in -1:0.2:1 ]  

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

すると下のように,バーが 2本とワイヤーフレームのグラフが表示される. バーを掴んで動かしてみよう.「このグラフを見る角度」を変えられるはずだ.便利だね!

bars

wireframe

簡易アニメーション

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

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

とすると、

┌ Info: Saved animation to 
│   fn = c:\home\julia-programs\v1.6\tmp.gif
└ @ Plots c:\julia\PKG\v1.6\packages\Plots\yfzIY\src\animation.jl:114

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

gif-sample



Appendix 2: ファイヤーウォール中で Julia を利用するためには

Julia のパッケージと呼ばれるライブラリ環境のインストールと更新は内部的に git, curl といった unix のネットワーク系コマンドを用いて行われる. そのため,firewall の中(たとえば阪大情報教育システムはそうである)では,適切な設定をしないとパッケージをうまく扱えない.

そこで,たとえば阪大情報教育システム(windows)上の Julia を用いるのであれば,(Julia インストール直後ぐらいに)次のような設定をしておく必要がある.

  この設定をしても外に繋がらないような場合は諦めよう…

1.git コマンドのための設定: Windows の メニュー → "Command Prompt" として command prompt を起動し,次の3つのコマンドを実行する.すると,とある設定ファイルが作られて下記の内容が書き込まれ, 以降のgit コマンドは proxy サーバを介して外へつながるようになる.

git config --global http.proxy http://toyonakans.ecs.cmc.osaka-u.ac.jp:3128
git config --global https.proxy http://toyonakans.ecs.cmc.osaka-u.ac.jp:3128
git config --global url."https://".insteadOf git://

2.curl コマンドのための設定:

2-a.おそらく c:\Users(もしくはユーザー)\アカウント名\.julia というディレクトリがあるので,その中に config というディレクトリを作る.

2-b.上で作ったディレクトリに startup.jl というファイルを作り,以下の2行を書き込んでおく.

1
2
ENV["HTTP_PROXY"] = "http://toyonakans.ecs.cmc.osaka-u.ac.jp:3128"
ENV["HTTPS_PROXY"] = "http://toyonakans.ecs.cmc.osaka-u.ac.jp:3128"

これで一応は良いはずだが,最近はこれも許可されていないかもしれない.


  1. 今の Julia では Plots package がグラフ描画のデフォルト的な存在だね. ↩︎

  2. そもそも jupyter という名前が JUlia + PYThon + R なのだ. ↩︎

  3. Atom エディタの開発が 2019年に実質的に停止した様子.そのため,Atom に依存していた Juno も先がないということで移行したのではないかと推測される. ↩︎

  4. 開発初期の syntax hilighting についてのブログ なんかは参考になるぞ. ↩︎

  5. 三角関数などを使って良いということだ.はっきり書くと、$L(n) = 2rn\sin(\pi/n)$ として良い、ということになるね. ↩︎

  6. この範囲を超えると,warning が出る.グラフは変化しない. ↩︎

  7. 実は jupyter 用の拡張機能は上でインストールした WebIO 対応のもの以外のものもある.今はずいぶん少なくなったが. 興味がある人は Anaconda3 のプロンプトを起動し,そこで conda install -c conda-forge jupyter_contrib_nbextensions とすると,「典型的な拡張機能のインストール」がなされる. jupyter のファイラー画面の上方のタブを見てみよう."Nbextensions" というタブが増えていて,そこをクリックすると拡張機能の一覧が出るはずだ. あとは触って解説を読むなどしてみると良い.ただし,python でしか有効でなく Julia では動かない機能もあったりするので,解説はよく読むこと. ↩︎