OS X ElCapitanにpyenv, pyenv-virtualenv, jupyterで環境構築

Mac OS X El Capitan にpyenv, pyenv-virtualenv, jupyterを入れて環境構築する話．

# Install pyenv, pyenv-virtualenv

```shell-session
$ brew install pyenv pyenv-virtualenv
```

# Install python and create virtual environment

```shell-session
$ PYTHON_CONFIGURE_OPTS="--enable-unicode=ucs2 --enable-framework=$(pyenv root)/versions/2.7.11" pyenv install 2.7.11
$ pyenv virtualenv 2.7.11 tech
```

`PYTHON_CONFIGURE_OPTS="--enable-unicode=ucs2"`をつけないと，あとで`jupyter notebook`でエラーになる↓
参考：http://qiita.com/sigmalogneko/items/b5c15f5229387bbfd53a

```shell-session
(test) foo-mbp:test foo$ jupyter notebook
Traceback (most recent call last):
  File "/Users/foo/.pyenv/versions/test/bin/jupyter-notebook", line 7, in <module>
    from notebook.notebookapp import main
  File "/Users/foo/.pyenv/versions/2.7.10/envs/test/lib/python2.7/site-packages/notebook/notebookapp.py", line 30, in <module>
    from zmq.eventloop import ioloop
  File "/Users/foo/.pyenv/versions/2.7.10/envs/test/lib/python2.7/site-packages/zmq/__init__.py", line 66, in <module>
    from zmq import backend
  File "/Users/foo/.pyenv/versions/2.7.10/envs/test/lib/python2.7/site-packages/zmq/backend/__init__.py", line 40, in <module>
    reraise(*exc_info)
  File "/Users/foo/.pyenv/versions/2.7.10/envs/test/lib/python2.7/site-packages/zmq/backend/__init__.py", line 27, in <module>
    _ns = select_backend(first)
  File "/Users/foo/.pyenv/versions/2.7.10/envs/test/lib/python2.7/site-packages/zmq/backend/select.py", line 27, in select_backend
    mod = __import__(name, fromlist=public_api)
  File "/Users/foo/.pyenv/versions/2.7.10/envs/test/lib/python2.7/site-packages/zmq/backend/cython/__init__.py", line 6, in <module>
    from . import (constants, error, message, context,
ImportError: dlopen(/Users/foo/.pyenv/versions/2.7.10/envs/test/lib/python2.7/site-packages/zmq/backend/cython/constants.so, 2): Symbol not found: _PyUnicodeUCS2_DecodeUTF8
  Referenced from: /Users/foo/.pyenv/versions/2.7.10/envs/test/lib/python2.7/site-packages/zmq/backend/cython/constants.so
  Expected in: flat namespace
 in /Users/foo/.pyenv/versions/2.7.10/envs/test/lib/python2.7/site-packages/zmq/backend/cython/constants.so
```

こうなってしまったら，

```shell-session
$ pyenv uninstall 2.7.10
$ PYTHON_CONFIGURE_OPTS="--enable-unicode=ucs2" pyenv install 2.7.10
```
でやりなおし

また，`PYTHON_CONFIGURE_OPTS="--enable-framework=$(pyenv root)/versions/2.7.11"`はPythonをフレームワークモード（？）で動作させるためのオプション．これをやらないと`matplotlib`がうまく動かない．バージョン番号は適宜変える．
virtual envを使っている場合はどのみちうまくいかないが（後述）

# Use virtual environment

```shell-session
pyenv activate tech
```

# Install jupyter

```shell-session
pip install jupyter
```

# Matplotlib
iPython Notebook上で

```py
import matplotlib.pyplot
```
すると，エラーになる．

```
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-1-c845eb879342> in <module>()
     19 
     20 sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath('__file__')))))
---> 21 import handcraft_feature_extractor
     22 #import text2vec
     23 import config

/Users/foo/codes/pksha/chatbot-base/handcraft_feature_extractor.py in <module>()
      1 #!/usr/bin/env python
      2 # -*- coding: utf-8 -*-
----> 3 from feature_extractor import FeatureExtractor
      4 import MeCab
      5 import config

/Users/foo/codes/pksha/chatbot-base/feature_extractor.py in <module>()
      3 import matplotlib
      4 import numpy as np
----> 5 import matplotlib.pyplot as plt
      6 import MeCab
      7 import re, pprint

/Users/foo/.pyenv/versions/2.7.9/envs/pksha/lib/python2.7/site-packages/matplotlib/pyplot.py in <module>()
    112 
    113 from matplotlib.backends import pylab_setup
--> 114 _backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup()
    115 
    116 _IP_REGISTERED = None

/Users/foo/.pyenv/versions/2.7.9/envs/pksha/lib/python2.7/site-packages/matplotlib/backends/__init__.pyc in pylab_setup()
     30     # imports. 0 means only perform absolute imports.
     31     backend_mod = __import__(backend_name,
---> 32                              globals(),locals(),[backend_name],0)
     33 
     34     # Things we pull in from all backends

/Users/foo/.pyenv/versions/2.7.9/envs/pksha/lib/python2.7/site-packages/matplotlib/backends/backend_macosx.py in <module>()
     22 
     23 import matplotlib
---> 24 from matplotlib.backends import _macosx
     25 
     26 

RuntimeError: Python is not installed as a framework. The Mac OS X backend will not be able to function correctly if Python is not installed as a framework. See the Python documentation for more information on installing Python as a framework on Mac OS X. Please either reinstall Python as a framework, or try one of the other backends. If you are Working with Matplotlib in a virtual enviroment see 'Working with Matplotlib in Virtual environments' in the Matplotlib FAQ
```

http://matplotlib.org/faq/virtualenv_faq.html
を参考に，

`PATHTOENV/bin/frameworkpython`を作成し，実行権限付与

```bash:~/.pyenv/versions/tech/bin/frameworkpython
#!/bin/bash

# what real Python executable to use
PYVER=2.7
PATHTOPYTHON=/usr/bin/
PYTHON=${PATHTOPYTHON}python${PYVER}

# find the root of the virtualenv, it should be the parent of the dir this script is in
ENV=`$PYTHON -c "import os; print os.path.abspath(os.path.join(os.path.dirname(\"$0\"), '..'))"`

# now run Python with the virtualenv set as Python's HOME
export PYTHONHOME=$ENV
exec $PYTHON "$@"
```

```shell-session
$ chmod +x ~/.pyenv/versions/tech/bin/frameworkpython
```

この状態で

```shell-session
$ frameworkpython -m IPython notebook
```

でIPython Notebookを起動すると，`import matplotlib.pyplot`が動く．
`frameworkpython`で，使用するpythonをsystemのものに置き換えている？
なので，今回の例にかぎらず，`virtualenv`のPythonを使うせいでエラーになっているっぽい問題に遭遇したら，代わりに`frameworkpython`で実行してみるとよい．

しかし，

```shell-session
$ frameworkpython -m jupyter notebook
```
だとうまくいかない．
気持ち悪いのでなんとかしたい．

http://www.wirywolf.com/2016/01/pyplot-in-jupyter-inside-pyenv-on-el-capitan.html
を参考に，

```shell-session
$ jupyter --paths
config:
    /Users/foo/.jupyter
    /Users/foo/.pyenv/versions/2.7.9/envs/pksha/etc/jupyter
    /usr/local/etc/jupyter
    /etc/jupyter
data:
    /Users/foo/Library/Jupyter
    /Users/foo/.pyenv/versions/2.7.9/envs/pksha/share/jupyter
    /usr/local/share/jupyter
    /usr/share/jupyter
runtime:
    /Users/foo/Library/Jupyter/runtime
```

`data:`の一番目，`/Users/foo/Library/Jupyter`の下に新しくKernelを定義する．

```shell-session
$ mkdir -p ~/Library/Jupyter/kernels/matplotlib
$ vi ~/Library/Jupyter/kernels/matplotlib/kernel.json
```

```json:~/Library/Jupyter/kernels/matplotlib/kernel.json
{
 "argv": [ "/Users/foo/.pyenv/versions/tech/bin/frameworkpython", "-m", "ipykernel",
          "-f", "{connection_file}"],
 "display_name": "matplotlib",
 "language": "python"
}
```

これで，`matplotlib`という名前でKernelが定義された．

普通に`jupyter notebook`を実行して，
Jupyter Notebook上で作業するときに，Kernelを`matplotlib`にしてやればよい．