これまでの Python での仕事をすこしずつ Julia に移行する試みのひとつとして、Jupyter Lab 上で Julia を動かす環境を構築しました。Jupyter を駆動する Python の仮想環境と Jupyter の環境の関連などで混乱したので、整理してまとめます。
単に Jupyter 上で Julia が動くだけでなく、既存の Python 資産を素直な形で利用したかったので、
- Python の仮想環境を活用すること、
- Python の仮想環境にインストールした Jupyter を利用すること、
- Julia から仮想環境上の Python パッケージを利用できること
を目標とし、これらを達成しました。
設定した環境は macOS Monterey (v12.3), Apple M1 の ARM 環境です。環境依存性はあまりないので、macOS の Rosetta 環境や各種 Linux でも同様でしょう。Windows では確認していません。
動作確認は以下を実施しました。
-
PlotlyJS を用いた可視化
Julia にネイティブ対応したパッケージを用いた検証実験。 -
Plotly Express を用いた可視化
外部関数呼び出しインタフェイスの PyCall.jl を介して Python 用のパッケージを呼び出した検証実験。
ごちゃごちゃした説明は抜きに、コードだけ見たい方は私の GISTを見るとよいかもしれません。Mac 上の二種類の Python 環境を用いて、自動的に環境構築するコードになっています。
構築方法とその概要
-
Jupyter を駆動するための
venv
仮想環境を作成し、Jupyter Lab とその拡張機能をインストールします。 -
IJulia は Julia 用の Jupyter バックエンドです。このパッケージが Jupyter と Julia のなかだちをしてくれます。Jupyter の在処を Julia 側に伝えるために環境変数 (
JUPYTER
) を設定します。Julia から Python の資産を利用する場合、もうひとつの大切な環境変数があります。Python インタプリタを指し示す
PYTHON
変数は Julia が PyCall パッケージを介して Python 資産を探すときのとっかかりを与えます。 -
Julia を起動し、環境を設定・構成します。これで実行環境の準備が整います。
Jupyter Lab 環境の構築
まず、Python の仮想環境を新規構築します。以下の例では $HOME/.venvs/plotly
に構築していますが、このディレクトリはどこに作成しても構いません。
以下の作業は Apple M1 を搭載した Mac の ARM 環境で実施しましたが、環境依存性は少ないです。Apple M1 Mac の Rossetta 環境や Linux 環境でもそのまま構築できると思います。Anaconda 版の Python でやっても問題はないでしょう。Windows については未確認です。
Jupyter Lab を駆動する Python は Jupyter Lab が対応する十分に新しい Python を利用して下さい。以下では Mac にもともと搭載されている /usr/bin/python3
を用います。Homebrew 版 (/opt/homebrew/bin/python3.9
) でも同様の手順で動作することを確認しています。
では、仮想環境を作成し、利用しましょう。
$ venv=$HOME/.venvs/plotly # 便利のよいディレクトリを指定して下さい
$ mkdir -p $venv
$ /usr/bin/python3 -m venv $venv
$ source $venv/bin/activate
次に仮想環境に必要なソフトウェアをインストールします。
$ $venv/bin/pip install --upgrade pip jupyterlab
$ $venv/bin/jupyter labextension install jupyterlab-plotly
pip
を使って Jupyter Lab をインストールします。
第二行目は Julia 用の強力なデータ可視化パッケージの PlotlyJS と Jupyter Lab を連携させるための設定です。データ可視化に興味がない人は必要ありません。
二番目のコマンドで jupyter
のパスを明示している点は大切です。第一行目でインストールしたばかりの Jupyter は PATH に含まれているはずですが、シェルのキャッシュに載っていないようです。このため、単に jupyter labextension ...
と起動すると、どこか別の環境の Jupyter 環境へのインストールが始まります。また、Jupyter が起動したときに、あるべき拡張機能がインストールされていないために動作がおかしくなります。
※ このほかに利用したい Python パッケージがあったら、ここでインストールしておいて下さい。
環境変数群の設定
IJuliaとJupyterの連携 (JUPYTER
): IJulia から IJulia.jupyterlab()
関数を介して Jupyter Lab を開始するときに起動すべき Jupyter コマンドの在処を指定します。すでに仮想機械に Jupyter をインストールしてあるので、そのパスを与えます。
$ export JUPYTER=$venv/bin/jupyter
※ この変数の設定を変更したときは、その変更内容を IJulia パッケージに通知するために、Julia パッケージの再構成 (Pkg.build("IJulia")
)が求められるようです。環境変数設定を誤ったときに、環境変数を変更しただけでは設定がうまく IJulia に通知されないようです。
JuliaとPython仮想機械の連携 (PYTHON
): Julia から PyCall パッケージを介して Python 資産にアクセスするときに、探索すべき仮想機械の在処を指し示すために、仮想機械の Python インタプリタの場所を設定します。
$ export PYTHON=$venv/bin/python3
この変数の設定を変更したときは、その変更内容を PyCall パッケージに通知するために、PyCall パッケージの再構成(Pkg.build("PyCall")
)が求められるようです。
Juliaの環境構築
Julia の外部環境は設定がすみました。
いよいよ Julia を起動し、残りの環境設定を施します。
-
IJulia
: Jupyter Lab とのなかだちをするパッケージなのです。Jupyter を利用する上で必須のパッケージです。 -
PlotlyJS
: 可視化のために使うパッケージなので、可視化に興味がなければ不要です。 -
PyCall
: Julia から Python のパッケージやプログラムをアクセスするためのパッケージです。今回の例では、Python版の Plotly を利用するときに用います。
これらのパッケージをインストールするために Pkg
パッケージを利用します。Julia REPL のパッケージモードを利用しても構いません。
必要ないかもしれませんが、念のためここでインストールするすべてのパッケージを再構成 (Pkg.build(pkg)
) しています。
$ mkdir sample
$ cd sample
$ julia --project=.
julia> using Pkg
julia> for pkg in ["IJulia", "PyCall", "PlotlyJS"]
Pkg.add(pkg); Pkg.build(pkg)
end
お疲れさま。これで準備完了です。
Jupyter の起動
あとは、IJulia パッケージの jupyterlab()
関数を呼べば Jupyter Lab が起動するはずです。
julia> using IJulia
julia> jupyterlab()
環境変数 (JUPYTER
と PYTHON
) が環境構築のときだけに必要なのか、IJupyter や PyCall を呼ぶたびに必要なのかは確認していないのですが、不安なので私は毎回、設定しています。でも、面倒な手作業を避けるために小さなシェルスクリプト(lab
)を用意しています。
#!/bin/bash
#=
venv=$HOME/.venvs/plotly
export JUPYTER="$venv/bin/jupyter"
export PYTHON="$venv/bin/python3"
# Python 仮想環境の起動
source $venv/bin/activate
# Julia の起動
exec julia --project=. --startup-file=no -e 'include(popfirst!(ARGS))' "$0" "$@"
=#
using IJulia
jupyterlab()
実行の確認
データ可視化パッケージの PlotlyJS を利用した以下のコードは20個の乱数値を折れ線グラフに描画します。
using PlotlyJS
plot(rand(20))
環境がうまく構築できていれば、(結果は毎回異なりますが)以下のような出力が得られるでしょう。
次は PyCall を使って、Python の資産を利用する例です。
import PyCall
px = PyCall.pyimport("plotly.express")
gapminder = px.data.gapminder()
animation_fig = px.scatter(gapminder,
x="gdpPercap", y="lifeExp",
log_x=true,
hover_name="country",
size="pop", size_max=40,
color="continent",
facet_col="continent",
width=800,
animation_frame="year")
animation_fig.update_xaxes(tickfont=Dict("size" => 8))
animation_fig
これを実行すると、以下のような出力が得られます。下部のボタンでアニメーションを再生したり、スライダー操作で年ごとのデータを分析することができます。
このコードでは、Python 資産にアクセスするための PyCall を利用しています。PyCall.pyimport("plotly.express")
によって、Python 用のデータ可視化パッケージ Plotly の機能にアクセスしています。
この Python パッケージには「FACTFULLNESS」の著作でも知られるハンスロスリングの GapMinder データセットが含まれています。これを読み込み、Plotly Express によって散布図を生成し、その animation_frame
属性によってアニメーションを付加しています。
Plotly Express の使い方は、@driller, 小川、古木著の「Pythonインタラクティブ・データビジュアライゼーション入門」のコードのほぼ丸パクリです。