Execution of "%matplotlib notebook" before "import matplotlib" fails
Description
%matplotlib notebook
generates the error
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Cell In[1], line 1
----> 1 get_ipython().run_line_magic('matplotlib', 'notebook')
File /lib/python3.10/site-packages/IPython/core/interactiveshell.py:2369, in InteractiveShell.run_line_magic(self, magic_name, line, _stack_depth)
2367 kwargs['local_ns'] = self.get_local_scope(stack_depth)
2368 with self.builtin_trap:
-> 2369 result = fn(*args, **kwargs)
2370 return result
File /lib/python3.10/site-packages/IPython/core/magics/pylab.py:99, in PylabMagics.matplotlib(self, line)
97 print("Available matplotlib backends: %s" % backends_list)
98 else:
---> 99 gui, backend = self.shell.enable_matplotlib(args.gui.lower() if isinstance(args.gui, str) else args.gui)
100 self._show_matplotlib_backend(args.gui, backend)
File /lib/python3.10/site-packages/IPython/core/interactiveshell.py:3522, in InteractiveShell.enable_matplotlib(self, gui)
3501 def enable_matplotlib(self, gui=None):
3502 """Enable interactive matplotlib and inline figure support.
3503
3504 This takes the following steps:
(...)
3520 display figures inline.
3521 """
-> 3522 from matplotlib_inline.backend_inline import configure_inline_support
3524 from IPython.core import pylabtools as pt
3525 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
File /lib/python3.10/site-packages/matplotlib_inline/__init__.py:1
----> 1 from . import backend_inline, config # noqa
2 __version__ = "0.1.6" # noqa
File /lib/python3.10/site-packages/matplotlib_inline/backend_inline.py:6
1 """A matplotlib backend for publishing figures via display_data"""
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the BSD 3-Clause License.
----> 6 import matplotlib
7 from matplotlib import colors
8 from matplotlib.backends import backend_agg
ModuleNotFoundError: The module 'matplotlib' is included in the Pyodide distribution, but it is not installed.
You can install it by calling:
await micropip.install("matplotlib") in Python, or
await pyodide.loadPackage("matplotlib") in JavaScript
See https://pyodide.org/en/stable/usage/loading-packages.html for more details.
Reproduce
- On a new jupyter lite notebook
- Type
%import matplotlibin the first cell. Do NOT import matplotib beforehand - Execute the cell.
Expected behavior
This code should execute without any visible output (and enable the notebook mode for matplotlib). At the moment, this works if you import matplotlib beforehand but in the Jupyter lab context both options work.
Context
Jupyter lite version : Version 0.1.0-beta.17
matplotlib is not installed by default in jupyterlite, you need to execute %pip install matplotlib before execute your codes.
AFAICT, it is actually installed by default. At least I can import it and make some plots without any pip install:

My issue here is that in Jupyterlite,
%matplotlib notebook
import matplotlib
won't work
while
import matplotlib
%matplotlib notebook
does. Both work in the Jupyter lab setting (AFAICT).
@boisgera For jupyterlite, it use pyodide.runPython(code_string) to run codes.
when code_string == "import matplotlib", pyodide can detect it (like import pkg_name regex), and will help user to automatically and silently install matplotlib (You can open developer tool > Network tab, to see the network requests to confirm it).
when code_string == "%matplotlib notebook", import matplotlib is invoked inside but cannot be detected by pyodide.
Ah, I was not aware of that, thanks @qqdaiyu55 , it's enlightening! And indeed, if I do for example
exec("import matplotlib.pyplot as plt")
in a notebook, I end up with the same failure and error message. Same thing if I define a matplotlib_loader.py file whose content is:
import matplotlib
and make a
from matplotlib_loader import *
in the notebook.
Would it be possible to use import hooks (https://docs.python.org/3/reference/import.html#import-hooks) to have the same auto-loading property on import, but with a more robust behavior ? (Any import could be detected this way AFAICT, including the one triggered by %matplotlib notebook.)
Regards,
Sébastien
Moved the issue to the pyodide kernel repo since this appears to be working fine with the xeus python kernel when matplotlib is pre-installed: