Jupyter, Ipythonの設定　~起動、グラフの日本語表示、エイリアス、インライン表示、スタートアップモジュールインポート~

# 起動


## Ipython

ターミナルに`ipython`と打ち込む。

または、cmder使っているので、タスク(win+alt+t)に以下を登録した。

```
cmd /k "%ConEmuDir%\..\init.bat" -new_console:d:%HOME%\python & ipython
```

`init.bat`してから立ち上げると、shellコマンドとして`!head`とか使える。





## Jupyter qtconsole

ターミナルに`jupyter qtconsole --style=monokai`

`--style=monokai`しなくてもいいけど、背景白のコンソールは見た目が残念なので、スタイルを変える。
[ipythonのqtconsoleの色やフォントを設定する](www.mwsoft.jp/programming/numpy/ipython_qtconsole.html)←この辺が詳しい。

cmderには


```shell:aliasに登録した
cmd /k "jupyter qtconsole --style=monokai" -new_console:t:"Jupyter" -new_console:b
```

または

```shell:タスク(win+alt+t)に登録した
"jupyter qtconsole --style=monokai" -new_console:b -new_console:d:%HOME%\python
```


## Jupyter notebook

ターミナルに`jupyter notebook`と打ち込む

cmderには

```shell:タスク(win+alt+t)に登録した
jupyter notebook -new_console:t:"Jupyter Notebook" -new_console:b
```





# グラフの日本語表示


詳細は[matplotlib, seabornの日本語表示](http://qiita.com/u1and0/items/3b4d0f3e5514c9893d89)にも書いた。
以下は要約。



## matplotlibの日本語表示

`~/.matplotlib/matplotlibrc`を作成して、常時日本語フォントを使うようにする。

```txt:~/.matplotlib/matplotlibrc
font.family : IPAMincho
```




## seabornの日本語表示

`C:\tools\Anaconda3\Lib\site-packages\seaborn\rcmod.pyのrcmod.py`のset関数のデフォルト値のfontを"sans-serif"から"IPAMincho"などに変更する。

```python:rcmod.py
...
def set(context="notebook", style="darkgrid", palette="deep",
        font="IPAMincho", font_scale=1, color_codes=False, rc=None):
...
```


なお、これらの操作はIPAフォントなどを[独立行政法人　情報処理推進機構](http://ipafont.ipa.go.jp/old/ipafont/download.html)あたりから事前にインストールしておく必要がある。

~~既にインストールしてある、MS明朝とかでも可能なはず。matplotlibrc内に書き込む名前がわからないので、知っている人は教えて下さい。~~
True type font(ttf)だからIPAフォントはpythonの日本語表示ができるらしい。Takaoフォントとかではできなかった。日本語化グラフ表示に使えるフォントは今のところIPAフォントしか知りません。

書き換えたら、**`~/.matplotlib/fontList.py3k.cache`といったキャッシュファイルも削除**して再度matplotlib等をインポートすることで日本語フォントが適用される。←これ結構忘れがち










# エイリアスとグラフ表示の修正

プロファイルを設定していなければ、プロファイルを作るべく、ターミナルに以下を入力。プロファイルの名前をつけることもできるが、<name>のところを空欄にすれば"default"の名前が付けられる。

```shell:プロファイルを作成する
$ ipython profile create <name>
```

上のコマンドで生成された`~\.ipython\profile_default\ipython_config.py`に以下を追加する。



```python:ipython_config.py
c.AliasManager.user_aliases = [
    # shell command
    ('ls', 'ls  --show-control-chars -F --color'),
    ('grep', 'grep --color'),
    ('grepx', 'grep --color -nriC'),
    ('find', 'find . -name'),

    # git
    ('g', 'git'),
    ('gf', 'git flow'),

    # add,commit,push
    ('ga', 'git add'),
    ('gaa', 'git add .'),
    ('gan', 'git add -n .'),
    ('gaundo', 'git reset HEAD'),
    ('gc', 'git commit'),
    ('gac', 'git commit -am'),
    ('gcundo', 'git commit --amend'),
    ('gp', 'git push'),
    ('gpo', 'git push origin'),

    # status
    ('gs', 'git status --short --branch'),
    ('gd', 'git diff --color-words'),
    ('gls', 'git ls-files'),
    ('gl', 'git log --oneline --all --graph --decorate'),

    # branch
    ('gb', 'git branch'),
    ('gch', 'git checkout'),
    ('gm', 'git merge'),
    ('gt', 'git tag'),
]

c.InteractiveShellApp.exec_lines = ['%load_ext autoreload', '%autoreload 2']
c.InlineBackend.rc = {'font.family': 'IPAMincho',
                      'figure.facecolor': (1, 1, 1, 1),
                      'savefig.dpi': 72,
                      'figure.subplot.bottom': 0.125,
                      'figure.edgecolor': (1, 1, 1, 1)}

```



やっていること

* `c.AliasManager.user_aliases`: エイリアスを追加してipython shellを使いやすくする
    * lsやgrepのようなshellコマンド
    * gitのコマンド
* `c.InteractiveShellApp.exec_lines`: ipython実行時に次のリスト内にあるマジックコマンドを実行
* `c.InlineBackend.rc`: グラフをインライン表示したときに、背景色とticksやタイトルがかぶってしまうのを防ぐ。


![jupyter_background_hide.PNG](https://qiita-image-store.s3.amazonaws.com/0/113494/cdd0a035-1849-243f-4a3f-9077cdf3c974.png)

タイトルやticksが黒文字なので見えない。
こういうのがいやだ。
`c.InlineBackend.rc`の設定を弄ってやると、グラフの色を透明から変更できる。





# Ipython, Jupyterのスタートアップ

`~\.ipython\profile_default\startup`ディレクトリに保存された.py, .ipyファイルはIpython, Jupyter 開いたときに自動実行される。
使用しているのは以下の二つ。

* 01_startup.ipy
* 02_inline.ipy

>
ちなみに実行されるときは名前順にソートされて実行されるので、
>
* startup.ipy
* inline.ipy
> 
とすると`inline.py`が実行されたのち`startup.py`が実行される。
`startup.py`に`matplotlib`インポートが記述されているので、`inline.py`を先にインポートするとインポートエラー。
ゆえにファイル名の先頭に数字`01`, `02`を付けて`startup.py`が先に実行されるようにしている。


## 01_startup.ipy

モジュールのインポートを行う。

```python:01_startup.ipy
__modules__ = ('numpy',
           'pandas',
           'matplotlib.pyplot',
           'seaborn')
__standfor__ = {'numpy': 'np',
            'pandas': 'pd',
            'matplotlib.pyplot': 'plt',
            'seaborn': 'sns'}

for __module__ in __modules__:
    __execution__ = 'import %s as %s' % (__module__, __standfor__[__module__])
    print(__execution__)
    exec(__execution__)
```

ipythonやjupyter立ち上げたときに、インポート中のモジュールを標準出力に出力しながら、`numpy, pandas, matplotlib.pyplot, seaborn`をインポートしてくれる。

詳細は[スタートアップ時にインポート中のモジュールを表示](http://qiita.com/u1and0/items/aae3e24c73692d28f501)にも書いた。



## 02_inline.ipy

グラフのインライン表示を指示する。

```python:02_inline.ipy
__inline__ = 'matplotlib inline'
__gui__ = 'matplotlib auto'
try:
    get_ipython().magic(__inline__)
    print('%' + __inline__)
except:
    get_ipython().magic(__gui__)
    print('%' + __gui__)
    print("If you'd like to use `plt.show()` command,")
    print('you can type `plt.ioff()`/`plt.ion()` to turn interactive mode off/on.')
```

実行していることは、`%matplotlib inline`を実行してみて、エラーが出たら`%matplotlib auto`を実行する。autoはデフォルトで開くqt5などのGUIアプリケーションでグラフを開く。(要はデフォルトの動作を行う。)
エラーはコンソール出力できないIpython上などでinline表示をしようとすると、以下のような`UnknownBackend`というエラーが返される。

```
UnknownBackend: No event loop integration for 'inline'. 
Supported event loops are: qt, qt4, qt5, gtk, gtk2, gtk3, tk, wx, pyglet, glut, osx
```

plt.show()を再び使いたいときの説明メッセージ

```
If you use `plt.show()` command,
you should use `plt.ioff()` to turn interactive mode off.
```

は即座にplotするモードを終了させて、`plt.show()`による描画に戻したいときは`plt.ioff()`と打ってください、って意味。


**更新　2016/11/13**
`__hogehoge__`のように変数をアンダーバー二つでくくると外部から見えなくなる。
影響ないと思うけど、後になって「指定した覚えのないmoduleとかstandforとかいう変数ナンダ？？？」ってならないようにする措置。


## inline.ipy動作時の注意点

### ipythonの場合

![ipython_qt5.PNG](https://qiita-image-store.s3.amazonaws.com/0/113494/89288801-8ffd-9fb5-28c9-718691a4a32f.png)

`plt.<コマンド>`を打つと即座にグラフが表示される


![ipython_ioff.PNG](https://qiita-image-store.s3.amazonaws.com/0/113494/47390c5b-0b69-b895-28c4-a8b601d40779.png)

plotをいくつか重ねたい場合、`plt.ioff()`を打つと、対話モードが終了し、`plt.show()`を打たないとqt5にグラフ表示されない、通常の状態に戻る。



### jpython qtconsoleの場合

![jupyterconsole_japanese2.PNG](https://qiita-image-store.s3.amazonaws.com/0/113494/145bd8fb-eb8b-fdbf-0a72-b2d1e910e6a5.png)

ipythonと同様に`plt.<コマンド>`で即座に表示される


![jupyterconsole_japanese_barabara.PNG](https://qiita-image-store.s3.amazonaws.com/0/113494/a2bc94f5-603c-39f9-2ddc-b1bc1d3fb4fe.png)
jupyter qtconsoleは`plt.ioff()`をしてもプロットが重なってくれない


![jupyter_backslasherro.PNG](https://qiita-image-store.s3.amazonaws.com/0/113494/bc23e0cc-3235-d347-2fdc-cc0db01c58b0.png)

グラフの作り方として、バックスラッシュを続けて、コマンドを続ける
そのままenter(shift+enter)するとエラーしてしまうので




![use_backslash.PNG](https://qiita-image-store.s3.amazonaws.com/0/113494/b52a0d7d-76df-79b5-0fe0-6c7e3b0795c8.png)

面倒くさいけど、表示したい段階になったらバックスラッシュを消してからenter(shift+enter)すると重ねて描ける。



### jupyter notebookの場合

![jupyternotebook_japanese.PNG](https://qiita-image-store.s3.amazonaws.com/0/113494/28c62508-c3c6-dcec-ca5a-5cccd67c3464.png)


jupyter notebookであればセルごとにまとめてプロットしてくれるので、jupyter qtconsoleみたいな問題は起こらない。





## 参考

* [ipythonでmatplotlibのグラフをinline表示する - 計算物理屋の研究備忘録](http://keisanbutsuriya.hateblo.jp/entry/2015/11/28/220429)
* [ipythonのqtconsoleの色やフォントを設定する](www.mwsoft.jp/programming/numpy/ipython_qtconsole.html)
* [matplotlib, seabornの日本語表示](http://qiita.com/u1and0/items/3b4d0f3e5514c9893d89)
* [スタートアップ時にインポート中のモジュールを表示](http://qiita.com/u1and0/items/aae3e24c73692d28f501)




# モジュールのリロード

モジュールをインポートして何か試したあとに「ここのメッセージわかりにくいなぁ」とか「この定数間違えた！」とかよくあること。
そういう時は修正して再度プログラム走らせたいのだが、エディタ上で書き換えた修正が反映されなくてよく戸惑うので解決法。


## 修正してimportしても修正が適用されない件

pythonのimportはメモリの効率化のため、一度importされたモジュールは再度importされないようになっている。


```python:hello.py
def hello():
    print('hello')
```



```pycon:ipythonで実行
[In] import hello
[In] hello.hello()
[Out] hello
```


```python:hello.py書き換え
def hello():
    print('f**k!')
```


```pycon:修正後のhello()
[In] import hello
[In] hello.hello()
[Out] hello
## ここは'f**k!'と表示されたかった。
```

## impモジュール

それでも修正したプログラムが修正適用されてインポートされないのは使えなさ過ぎるので、impモジュールでリロードできる。

```pycon:imp.reload()
[In]import hello
##  ~~hello.pyの書き換え~~ 
[In]import imp
[In]imp.reload(hello)
[In] hello.hello()
[Out] f**k!
```


# マジックコマンド`%autoreload`

ipython上では`%autoreload`というマジックコマンドが用意されているので、impモジュールをインポートしなくてもリロードを簡単にできる。
`%autoreload`自体を`%load_ext`でロードしてこないとダメだけどね。


```pycon:%autoreload()
[In] %load_ext autoreload  # マジックコマンド%autoreloadをロードする
[In] %autoreload hello
[In] hello.hello()
[Out] f**k!
```


## すべてのモジュールを常にリロード

コンソールの最初で`%autoreload 2`と打てば、すべてのモジュールはimportした際に差分チェックされて、書き換えられてたらリロードしてくれる。

```pycon:すべてのモジュールを常にリロード
[In] %autoreload 2
```


## ipython実行時に常に`%autoreload 2`

ipython実行時に常に`%autoreload 2`を打ち込みたいとき、`~\.ipython\profile_default\ipython_config.py`に以下のように書き込まれると、ipython実行時に`%load_ext`と`%autoreload 2`が実行されたことになる。

```pycon:ipython立ち上げ時に%autoreload2実行
c.InteractiveShellApp.exec_lines = ['%load_ext autoreload', '%autoreload 2']
```





## 参考
[ipython とmodule reload と 設定ファイル](http://qiita.com/ksomemo/items/74607f4dd3222fe9273d)
[ipython を起動しながら自作モジュールを修正した場合](http://qiita.com/Accent/items/f6bb4d4b7adf268662f4)
[u1and0/dotfiles/.jupyter](https://github.com/u1and0/dotfiles/tree/master/.jupyter)
[u1and0/dotfiles/.ipython](https://github.com/u1and0/dotfiles/tree/master/.ipython)