VSCode+Jupyter Extensionでpyvistaが起動しない

Issue
import pyvista as pv
sphere = pv.Sphere()
# short example
sphere.plot(jupyter_backend="trame")
# long example
plotter = pv.Plotter(notebook=True)
plotter.add_mesh(sphere)
plotter.show(jupyter_backend="trame")
ERROR:root:Cannot create GLX context. Aborting.
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
2024-09-10 16:22:51.339 ( 2.946s) [ 7FCE769371C0]vtkXOpenGLRenderWindow.:651 ERR| vtkXOpenGLRenderWindow (0x563c7c092e40): Cannot create GLX context. Aborting.
Environment
pyvista = {extras = ["jupyter"], version = "^0.44.1"}
jupyter-server-proxy = "^4.4.0"

コミッターの一人がVSCodeでnotebookを起動しても jupyter-server-proxy
が自動的に起動しないのでportに明示的にforwardするか独自のproxyを実現する必要があるというコメントをしている。
drive by comment: our backend relies on jupyter-server-proxy by default. Running notebooks in VSCode will not launch jupyter-server-proxy -- its specific to jupyter lab/notebook. You will need to forward the ports explicitly or set up your own proxying mechanism.

公式ドキュメントには「dockerなどのリモートホストでPyVistaをホストする場合はTrame backendに加えて jupyter-server-proxy
か trame-jupyter-extension
のいずれかが必要」とある。
When using PyVista in Jupyter that is hosted remotely (docker, cloud JupyterHub, binder, or otherwise), you will need to pair the Trame backend with either jupyter-server-proxy or trame-jupyter-extension.

vtkの問題? -> GPUに対応したVTKを自分でビルドする。

参考: vtkとvtk-osmesaの違い
vtk-osmesa の場合は依存したapt packageのインストールが不要になるらしい。
Why is this useful
No more virtual framebuffers and no more apt installing! Goodbye xvfb!
The vtk-osmesa wheel bundles all the needed dependencies and is specifically for off-screen rendering. This wheel is optimal for managed, deployed environments like we often see on platforms like MyBinder, Heroku, Google Colab, SageMaker, etc.
Simply pip install this wheel for your JupyterLab environment and start using PyVista!
Further, this will make CI testing quite a bit easier for downstream projects

諸々環境汚れてたのでcontainerを作り直したら起動した。
import pyvista as pv
pv.global_theme.trame.server_proxy_enabled = True
pv.global_theme.trame.server_proxy_prefix = "http://localhost:"
print(
pv.global_theme.trame.server_proxy_enabled,
pv.global_theme.trame.server_proxy_prefix,
)
pv.Cube().plot()
結論として、vtk-osmesa
+ jupyter-server-proxy
でコンフィグをちゃんと設定したら動いた。
インストールしたpackage(余計なものを含むかもしれない)
jupyterlab = ">=3"
ipywidgets = "^8.1.5"
trame = "^3.6.5"
trame-vtk = "^2.8.10"
trame-vuetify = "^2.7.1"
pyvista = { version = "^0.44.0", extras = ["all", "trame"] }
jupyter-server-proxy = "^4.4.0"
vtk-osmesa = { version = "^9.3.1", source = "vtk" }

jupyter-server-proxy
の設定は環境変数で設定しておくのが良い。
export PYVISTA_TRAME_JUPYTER_MODE="extension"
export PYVISTA_TRAME_SERVER_PROXY_PREFIX="http://localhost:"

効果の切り分けをしてないが、VSCode側も設定変えてる。
remote.autoForwardPortsSource: process
remote.localPortHost: localhost

毎回成功するわけではなく、↑のissueで言っているように何回に一回か成功するイメージだった。