【JupyterLab】コールバックでセル出力を書き換える方法

2023-03-05

表題の通り、JupyterLab でボタンによる操作などのコールバックで、セル出力を更新する場合の方法。

結論

ipywidgets.Output を使う。

経緯

以前GoogleColabで強化学習AIとの対戦(GoogleColabでインタラクティブな処理をする)を行ってみたが、PCを自作したのでローカルマシンに入れたJupyterLab上で同様なことをやろうとしたところつまづいた。 ボタンのコールバックで盤面を更新してセルに出力していたのだが、IPython.displayの出力がセルの出力ではなくログに出力されてしまうため、Colabで動かした時とは違って、更新内容が反映されなくなってしまった。

方法

どうしたもんかとググったところやり方が見つかった: Updating output of cell after end of execution · Issue #4963 · jupyterlab/jupyterlab · GitHub

つまるところ、ipywidgets.Output を使うといいらしい。

セル内で out = Output() として作成しておいて、IPython.displaydisplayclear_outputを呼んでる箇所でwith out:としてもよいし、 ボタンのクリックハンドラ関数にデコレータ@out.capture()を指定してもよい。

動作原理はよく理解してないが、withやデコレータの関数での前後で出力先をそのOutputが関連しているセルに出力するよう切り替えてるんだろう、たぶん。

Colabで動くか?

逆にGoogleColabでipywidgets.Outputを指定したらどうなるか試してみたところ、つけても問題なく動くようだった。

そういう指定をしなくても動くColabはどうなっているのか、神。