ipywidgetsのチュートリアル(Using Interact)でinteract
関数がでてきます。これを使うとmatplotlibのグラフがダイナミックに操作できて楽しいです。
interactのスライドバーなり何なりで使ったパラメータを保存できたら便利だなと思ったのですが、意外と手間取ったのでメモしておきます。
環境
- JupyterLab 0.35.4
- ipywidgets 7.4.2
- Python 3.5.2
※ ipywidgetsをJupyterLabで使うためにはjupyter notebookとは別途でインストールが必要。詳しくはこちら。
$ jupyter labextension install @jupyter-widgets/jupyterlab-manager
# JupyterLab 0.35.4で使うためにはバージョン指定が必要
# jupyter labextension install @jupyter-widgets/jupyterlab-manager@0.38
コード
save_params.ipynb
%matplotlib inline
import ipywidgets as widgets
from IPython.display import display
import numpy as np
import matplotlib.pyplot as plt
# セーブボタン
button = widgets.Button(description='save')
display(button)
# ボタンをクリックしたときのprint文のために必要
# JupyterLabを使っていない場合は不要
output = widgets.Output()
display(output)
# 直前に登録したcallback
callback = None
@widgets.interact(
a=(0, 3, 0.1),
b=(-3, 3, 0.1)
)
def plot_sin_curve(a=1, b=0):
x = np.arange(-3, 3, 0.1)
y = np.sin(a * x + b)
plt.plot(x, y)
# ボタンをクリックしたときの処理
# JupyterLabでは通常widgetの出力は表示されないのでキャプチャする
@output.capture(clear_output=True)
def save_params(btn):
content = 'a = {}, b = {}'.format(a, b)
print('{} is saved!'.format(content))
# ボタンをクリックするたびにaおよびbの値をparams.txtに追記
with open('params.txt', mode='a') as f:
f.write('{}\n'.format(content))
# 直前のcallbackを削除する
global callback
if callback is not None:
button.on_click(callback, remove=True)
# クリックしたときの動作を登録
button.on_click(save_params)
callback = save_params
ポイントは
1. JupyterLabではipywidgets.Output()
を使って、widgetの出力をキャプチャする必要がある
2. widgetのon_click
を何回も呼ぶとcallbackが毎回appendされていくので、不要な場合は削除しておく
という2点です。