TL;DR

ipython notebook --pylab inlineのかわりにipython notebook --matplotlib inlineを使おう.もしくはipythonの始めに%matplotlib inlineを実行しておく.

iPython Notebookについて

周知の事実だとは思うが,iPythonは超便利なPythonのインタラクティブシェルだ.その一部としてiPython Notebookというのがあり,ブラウザでコードを実行できたり,実行結果をノートとして保存したり,matplotlibなどで描写したグラフをノートの中にそのまま表示したりできる.RでいうところのRstudio+knitrのような,解析レポートを作るときには重宝するツールとなっている.


http://nbviewer.ipython.org/gist/twiecki/3962843より

(http://nbviewer.ipython.org/gist/twiecki/3962843より)

で,iPython Notebookに関する記事を見ていると,だいたい以下のようなコマンドで実行している.

1
$ ipython notebook --pylab inline

ipython notebookで起動,それにくわえて–pylab inlineとすることでiPython Notebook内で描写したグラフが展開できて嬉しいわけだけど,一つ問題がある.それはpylabをインポートしている点だ.

無意識にpylabを使うとなにが危ないか

pylab自体は色々と便利なパッケージなんだけれども,そのpylabの挙動に少し問題がある.上で示したようなコマンドでpylabフラグを付けて実行すると,実は裏ではnumpyのモジュールがnpのエイリアスとともに,トップレベルでもインポートされている.実際にコマンドを叩いて確かめてみると以下のようになる.

1
2
3
4
5
6
7
$ ipython --pylab

In [1]: np.arange(0,10)
Out[1]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

In [2]: arange(0,10)
Out[2]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

どっちも実行できていて何の変哲もないように見えるんだけど,よくNumpyの実行環境で見るimport numpy as npの場合だと,1行目の書き方では実行できるが,2行目の書き方では実行できない.それが,pylabをインポートしているとどちらもできてしまう,正確に言えば,Numpyの関数がモジュール名もしくはエイリアスを先頭に付けなくても実行できてしまう.

ではこれの何が問題かというと,関数の名前がかぶるというわけだ.たとえば組み込み関数のsum()all()は,実はNumpyにも同様の名前の関数がある(sum(),all()).なのでpylabをインポートすると,勝手にsumやallがNumpyのモジュールのものに置き換わってしまう.

1
2
3
4
5
6
7
8
9
10
11
# pylabをインポートしない場合
$ ipython

In [1]: sum,all
Out[1]: (<function sum>, <function all>)

# pylabをインポートした場合
$ ipython --pylab

In [1]: sum,all
Out[1]: (<function numpy.core.fromnumeric.sum>, <function numpy.core.fromnumeric.all>)

意識的にpylabを使おうと思って書くコードなら良いんだけど,もしpylab関係なくいつもiPython Notebook使ってるからという感覚でpythonのコードを書いたとして,あとで普通のpythonで実行したら動かない,なんてことが起こりかねない.まあ気をつければ済む話かもしれないが,こういう地雷は踏まないに限る.

公式にも–pylabは使えなくなる見込み

あと,–pylabを使ってiPython Notebookを起動すると以下のような警告文が出る.

1
2
3
4
5
6
7
8
9
$ ipython notebook --pylab inline

[...]

[NotebookApp] WARNING | Starting all kernels in pylab mode is not recommended,
    and will be disabled in a future release.
    Please use the %matplotlib magic to enable matplotlib instead.
    pylab implies many imports, which can have confusing side effects
    and harm the reproducibility of your notebooks.

ということで,iPython Notebookを使うときには–pylabで読み込みをしないほうが良い.

pylabを使わないでinline表示させるには

–pylab inlineを回避する方法は2つある.

  • ipython notebook --matplotlib inlineで起動する
  • %matplotlib inlineをiPython Notebookの冒頭で実行しておく

こうすることによって,pylabのインポートを回避しつつiPythonのノート内でグラフを描写することができる.1つ目のiPythonのフラグで指定するほうが簡単だとは思うのだが,ぐぐってもこのコマンドで実行している例があまり出てこないのだけれども,たぶん問題無いと思う.

注意

ここまで読んだならわかるとは思うけれども,pylabの行儀悪いNumpyインポートを避けようということをしたわけだから,当然Numpyは別でインポートしないといけないし,そのへんのウェブページに載っているiPython Notebookの実行例とかのNumpyの関数の入ったコードはそのままでは実行できない.今回の方法を使っているなら,そのあたりは適宜読み替える必要がある.あんまり見たこと無い関数があったら,それがPythonの組み込み関数なのかNumpyやpylabの関数なのか疑ってかかろう.もしNumpyの関数なら,import numpy as npがされていることを確認したうえでnp.を関数の先頭につければ実行できる.なんかコードのサンプルをコピペしたけど動かないというときは,まあ大抵この問題だ.

元ネタ

追記(2015/01/25)

ipython notebookのコンフィグに追記しておく方法もあるようです.

参考

参考