昔、Emacsから使えないからjupyter notebookは使わないという旨の記事を書いた。 実際まだ、Emacsからは使えていないけど、最近はだいたいのコードをEmacs+pythonで書いて、実行やグラフを描く部分をjupyter notebookでやるということをよくやっている。
jupyter notebook内にグラフを描く方法として
%matplotlib inline
という文を実行しておくという方法がある。
大体の場合にはこれで間に合うが、3Dグラフを回したり、アニメーションを動かしたりすることができなかった。 調べてみると他にも色々できることがわかったのでまとめる。 この記事では以下のようなプロットを描く。
- 回転できる3D
- アニメーション
- スライドバー付き
- もっと綺麗なグラフを描く
markdownで出力すると全く触れなくなったので動画を作った。
回転できる3Dプロット
%matplotlib inline
でプロットを作成すると、ノートブックの中に画像として出力されてしまうので回せない。
%matplotlib notebook
を使うとノートブックの外に出力したときと同じように、インタラクティブなグラフが描ける。 こちらの3次元プロットを例として描く。
%matplotlib notebook from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt import numpy as np x = np.arange(-3, 3, 0.25) y = np.arange(-3, 3, 0.25) X, Y = np.meshgrid(x, y) Z = np.sin(X)+ np.cos(Y) fig = plt.figure() ax = Axes3D(fig) ax.plot_wireframe(X,Y,Z) plt.show()
スライドバーつき
ipywidgetsというやつを使えばできる。 jupyter notebookをインストールしただけで使おうとすると以下のコマンドを実行するように表示されたので、おとなしく従うと動くようになった。
sudo jupyter nbextension enable --py --sys-prefix widgetsnbextension
以下を実行すると、スライドバーが表示される。 このバーをいじると変数の値が動的に変わるので、コールバックにプロットを登録しておくと、スライドバーをいじるだけで勝手にプロットが変わる。
自分の環境では
%matplotlib notebook
とするとカクカクでいまいちだったが、
%matplotlib inline
にするといい感じ。
%matplotlib inline from ipywidgets import interact import numpy as np def scatter(num_data): x = range(num_data) y = [np.sin(t/5.0) for t in x] plt.plot(x, y) plt.show() interact(scatter, num_data=(1,200, 1), value=2)
ipywidgetsには他にもボタンとかプログレスバーとか色々あって、ノートを簡単なアプリにできる。
%matplotlib inline import pylab as plt import time from ipywidgets import FloatProgress from IPython import display prg = FloatProgress(min=0, max=99, value=1) display.display(prg) for i in range(100): prg.value = i time.sleep(0.01)
もっと綺麗なグラフを描く
matplotlibではなくて、plotlyというライブラリを使えばできる。 matplotlibと書き方が結構違うので、改めて覚えてまでやるほどかと言われると微妙だが、グラフは綺麗でかっこいい。 コードやグラフ、データをオンラインで共有したりもできるらしい。
デモのサイトを見ていると可能性を感じる。
from plotly.offline import iplot, init_notebook_mode import plotly.plotly as py from plotly.graph_objs import Scatter, Data init_notebook_mode(connected=True) trace0 = Scatter( x=[1, 2, 3, 4], y=[10, 15, 13, 17] ) trace1 = Scatter( x=[1, 2, 3, 4], y=[16, 5, 11, 9] ) data = Data([trace0, trace1]) unique_url = iplot(data, filename = 'basic-line')