coatless-quarto/pyodide

Shim/capture `seaborn` and/or `plotnine`

Opened this issue · 1 comments

Only the matplotlib graphs are captured and displayed with the matplotlib_pyodide.html5_canvas_backend. If we use seaborn such as:

import micropip
await micropip.install("seaborn")

# External Python package
import seaborn as sns

# Core Pyodide packages
import numpy as np 
import pandas as pd 

data = np.random.multivariate_normal([0, 0], [[5, 2], [2, 2]], size=2000)
data = pd.DataFrame(data, columns=['x', 'y'])

sns.displot(data['x']);

Then, we get an error of:

Error trace of attempting to render a `seaborn` graph
PythonError: Traceback (most recent call last):
  File "/lib/python311.zip/_pyodide/_base.py", line 573, in eval_code_async
    await CodeRunner(
  File "/lib/python311.zip/_pyodide/_base.py", line 393, in run_async
    coroutine = eval(self.code, globals, locals)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "", line 11, in 
  File "/lib/python3.11/site-packages/seaborn/distributions.py", line 2143, in displot
    g = FacetGrid(
        ^^^^^^^^^^
  File "/lib/python3.11/site-packages/seaborn/axisgrid.py", line 532, in __init__
    self.tight_layout()
  File "/lib/python3.11/site-packages/seaborn/axisgrid.py", line 123, in tight_layout
    self._figure.tight_layout(*args, **kwargs)
  File "/lib/python3.11/site-packages/matplotlib/figure.py", line 3222, in tight_layout
    renderer = get_renderer(self)
               ^^^^^^^^^^^^^^^^^^
  File "/lib/python3.11/site-packages/matplotlib/tight_layout.py", line 214, in get_renderer
    return backend_bases._get_renderer(fig)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/lib/python3.11/site-packages/matplotlib/backend_bases.py", line 1544, in _get_renderer
    print_method(io.BytesIO())
  File "/lib/python3.11/site-packages/matplotlib_pyodide/html5_canvas_backend.py", line 100, in print_png
    data = self.get_pixel_data()
           ^^^^^^^^^^^^^^^^^^^^^
  File "/lib/python3.11/site-packages/matplotlib_pyodide/html5_canvas_backend.py", line 77, in get_pixel_data
    img_URL = canvas.toDataURL("image/png")[21:]
              ^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'toDataURL'

The error disappears, but we do not get a canvas/output if we switch over to use the wasm backend, e.g.

matplotlib.use("module://matplotlib_pyodide.wasm_backend")

This still seems to be an issue. Commenting largely to follow the progress.