Jupyter で、Anaconda 2 と Anaconda 3 を共存 + おまけ(Julia)

([PS](http://qiita.com/utahka/items/ae14623ae81f85bea4f5#%E8%BF%BD%E8%A8%98-conda--jupyter-kernelspec) 2016/1/13)
[Jupyterがすごい勢いでやってくるからお前ら備えとけ（IPython Notebook + R）](http://qiita.com/tanemaki/items/7c74b35505dc372bc9c6) を読んでから、Jupyter にハマっています。

僕は Anaconda 2 と Anaconda 3 を共存させるために `pyenv` を使っているのですが、Jupyter で Anaconda のバージョンを切り替える際に、Jupyter終了してから pyenv で切り替えて再度起動！とするのが面倒になりました。New メニューから簡単に Python 2 と Python 3 を切り替えられたらいいのに！と思ったので、その辺の設定をやってみた話です。(Jupyter 初心者ですので、もっと簡単な方法があればコメント欄でお教えください...)

環境
----
- OS X 10.11.2 El Capitan
- pyenv (20151105) + virtualenv
- Jupyter 4.0.6

pyenv には、以下の Python がインストールされています。

- system
- 2.7.10
- 3.5.0
- anaconda-2.4.0
- anaconda3-2.4.0

じゅんび
--------
pyenv を使っていると良くも悪くも、pyenv で適用されている Python 環境が Jupyter に反映されます。

ただ、Jupyter を使っているときにはそれがちょっと邪魔になります。 Anaconda 2 と Anaconda 3 を簡単に切り替えられるようにしたいのです。そこで、それぞれの Anaconda を直接起動できるようにシンボリックリンクを次のように貼っておきます。

```bash
cd /usr/local/bin/ # PATH が通っているところに
ln -s ~/.pyenv/versions/anaconda-2.4.0/bin/python ./jupyter-python2
ln -s ~/.pyenv/versions/anaconda3-2.4.0/bin/python ./jupyter-python3
```

これから書く `kernel.json` というファイルのためにこんなことをしているのですが、もっといい方法ありますでしょうか...。

それでは、New メニューに Python 2 と Python 3 が一緒に表示されるようにしていきます。

Jupyter へPythonのカーネルを追加する
------------------------------------
まずは、以下のコマンドを叩きます。

```bash
mkdir -p ~/.ipython/kernels/python3
mkdir ~/.ipython/kernels/python2

touch ~/.ipython/kernels/python3/kernel.json
touch ~/.ipython/kernels/python2/kernel.json
```

このように、ホームディレクトリにある `.ipython/kernels` ディレクトリを作り、その下に `kernel.json` ファイルをもつディレクトリをそれぞれ作ることでカーネルを追加していくことができます。

それでは、お好きなエディタで、`~/.ipython/kernels/python2/kernel.json` を以下のように編集してください。

```python2/kernel.json
{
    "display_name": "Python 2"
    "language": "python"
    "argv": [
        "jupyter-python2",
        "-m", "ipykernel",
        "-f", "{connection_file}"
    ]
}
```

このように、`"argv"` の項目でコマンドやその引数を指定できます。なので、先ほどの `jupyter-python2` を指定しておけば、pyenv でどの Python が適用されていても、Jupyter では "Python 2" を選ぶことで、Anaconda 2 が起動してくれるようになります。

ここで、僕がはまったのが "ipykernel" の部分です。実は、いろいろなサイトを見ていると ここの部分は "IPython.kernel" と記述されています。僕の環境で同じようにすると、以下のような Warning がでてしまい、なんだかいい感じではないようでした。

```
ShimWarning: The `IPython.kernel` package has been deprecated.
```

そのときに出力されていた Warning 文からは、「いや、ipykernel ってやつを import してよ」という雰囲気をひしひし感じたので、今のように`ipykernel` を指定してみたら Warning が出なくなり、今の形に落ち着いています。

というわけで、そのことを踏まえて `python3` のほうも、次のように書いておきます。

```python3/kernel.json
{
    "display_name": "Python 3"
    "language": "python"
    "argv": [
        "jupyter-python3",
        "-m", "ipykernel",
        "-f", "{connection_file}"
    ]
}
```

これでおそらく、わざわざ pyenv に戻ることなく、notebook 内で切り替えが可能になるはずです。

(追記) conda + jupyter kernelspec
---------------------------------
[y__sama](http://qiita.com/y__sama) さんに、コメントで情報をいただき上のような頭の悪いことをしなくても良さそうなので、ここに追記させていただきます。

さて、Anaconda 界隈には `conda` というコマンドがあります。存在は知ってましたが、どういったものかは知りませんでした。(え。) 簡単にいうと、これも仮想環境をつくってくれるもののようです。

たとえば、anaconda3 の `conda` を使うことで、`~/.pyenv/versions/anaconda3-2.4.0/envs/jupyter-py2/` のように仮想環境 `jupyter-py2` を作れました。

その Python 仮想環境がアクティブな状態で、以下のようにコマンドを打つことで、`~/Library/Jupyter/kernels/` に自動でカーネルを追加してくれるようです。

```
jupyter kernelspec install-self --user
```

(追記) おや、ということは
----------------------
僕の使い方と生成される `kernel.json` の内容を見てみたところ、`conda` で仮想環境を作る必要もない気がしました。というわけで、(今のところの)以下のようになりました。

- pyenv に anaconda2 と anaconda3 を用意
- anaconda2 をアクティブにして、`jupyter kernelspec install-self --user`
- anaconda3 をアクティブにして、`jupyter kernelspec install-self --user`
- おわり

それにしても、`jupyter kernelspec install-self --user` を知ってれば全てが済む話でしたね。勉強になりました、ありがとうございました。

Julia も追加しておきたい！
--------------------------
ここまで来ると、Julia のカーネルも追加しておきたくなります。最近、巷で話題の Julia を勉強するのにも Jupyter は便利だと思いますので、この機会に追加しておきます。

### Julia のインストール
僕は、[Julialang.org/downloads](http://julialang.org/downloads/) から dmg ファイルを落としてきて、インストールしました。Homebrew でもできるようですが、ビルドに失敗したり面倒だった印象があるので、こっち推奨です(笑)

あとは、`/Applications/Julia-0.4.2.app/Contents/Resources/julia/bin/julia` に `julia` というエイリアスを貼っておきます。

### IJulia のインストール
次に、`IJulia` をインストールします。Julia を起動して、次のように打ちます。

```julia
Pkg.add("IJulia")
```

すると、僕の場合は最後の方で以下のようなエラーが出力されました。

```
===============================[ ERROR: IJulia ]================================

LoadError: __precompile__(true) but require failed to create a precompiled cache file
while loading /Users/"username"/.julia/v0.4/IJulia/deps/build.jl, in expression starting on line 2

================================================================================

=====================================[ BUILD ERRORS ]=====================================

WARNING: IJulia had build errors.

 - packages with build errors remain installed in /Users/"username"/.julia/v0.4
 - build the package(s) and all dependencies with `Pkg.build("IJulia")`
 - build a single package by running its `deps/build.jl` script

==========================================================================================
```

なんじゃ、これは...と思いましたが、駄目押しで以下のようにしたらうまくいきました。なぜ？笑

```julia
Pkg.rm("IJulia")
Pkg.add("IJulia")
```

### Julia から Jupyter notebook を起動
ここまでできると、Julia を起動して次のようにすることで、いつも通り notebook が起動します。

```
using IJulia
notebook()
```

New メニューにはこんな感じで追加されました。

<img width="340" alt="ijulia.png" src="https://qiita-image-store.s3.amazonaws.com/0/76596/6eba2868-1375-fe63-5d00-c80eb9957f00.png">

このあと、Jupyter notebook を Python で開いても New メニューには Julia の項目がありましたので、先ほどのように julia 用の `kernel.json` を書く必要は無さそうです。(必要になったら、そのとき追加するスタイル笑)

というわけで、晴れて Julia で notebook を書くことができるようになりました！お疲れ様でした。

(追記) ちなみに
-------------
この方法で追加した Julia カーネルは `~/Library/Jupyter/` に保存されます。

notebook の NEW メニューの "Julia 0.4.2" を "Julia" に変更したいとかいう細かいところにうるさい僕のような人は、ここの `kernel.json` を見ると良いと思います。

References
----------
今回、お世話になった記事やサイトです。こちらも参考にされると良いと思います！

- [Jupyter 環境設定補足 #pythontokai](http://qiita.com/antimon2/items/a8cd98257219773b9ef3)
- [Enable Python 3 kernel](http://jupyter.cs.brynmawr.edu/hub/dblank/public/Jupyter%20Help.ipynb#1.4.2-Enable-Python-3-kernel)
- [Making kernels for Jupyter](https://jupyter-client.readthedocs.org/en/latest/kernels.html?highlight=julia)
- [JuliaLang/IJulia.jl](https://github.com/JuliaLang/IJulia.jl)
- [Intermittently broken precompile](https://github.com/JuliaLang/julia/issues/13200)