mspass-team / mspass

Massive Parallel Analysis System for Seismologists
https://mspass.org
BSD 3-Clause "New" or "Revised" License
28 stars 11 forks source link

matplotlib interactive mode for notebooks is broken in current container #482

Closed pavlis closed 6 months ago

pavlis commented 6 months ago

Something is wrong with our python configuration for notebooks in the current container. Since MsPASS is using jupyter lab the documented way to enable interactive zoom and pan with matplotlb graphics is to use the incantation:

%matplotlib widget

When I use that I get this exception message that indicates a configuration issue:

---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[17], line 3
      1 print('plotting data for station ',d.member[8]['sta'])
      2 x=d.member[8]
----> 3 get_ipython().run_line_magic('matplotlib', 'widget')
      4 plt.plot(t,x.data)

File /opt/conda/lib/python3.10/site-packages/IPython/core/interactiveshell.py:2456, in InteractiveShell.run_line_magic(self, magic_name, line, _stack_depth)
   2454     kwargs['local_ns'] = self.get_local_scope(stack_depth)
   2455 with self.builtin_trap:
-> 2456     result = fn(*args, **kwargs)
   2458 # The code below prevents the output from being displayed
   2459 # when using magics with decorator @output_can_be_silenced
   2460 # when the last Python token in the expression is a ';'.
   2461 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):

File /opt/conda/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 /opt/conda/lib/python3.10/site-packages/IPython/core/interactiveshell.py:3648, in InteractiveShell.enable_matplotlib(self, gui)
   3644         print('Warning: Cannot change to a different GUI toolkit: %s.'
   3645                 ' Using %s instead.' % (gui, self.pylab_gui_select))
   3646         gui, backend = pt.find_gui_and_backend(self.pylab_gui_select)
-> 3648 pt.activate_matplotlib(backend)
   3649 configure_inline_support(self, backend)
   3651 # Now we must activate the gui pylab wants to use, and fix %run to take
   3652 # plot updates into account

File /opt/conda/lib/python3.10/site-packages/IPython/core/pylabtools.py:368, in activate_matplotlib(backend)
    363 # Due to circular imports, pyplot may be only partially initialised
    364 # when this function runs.
    365 # So avoid needing matplotlib attribute-lookup to access pyplot.
    366 from matplotlib import pyplot as plt
--> 368 plt.switch_backend(backend)
    370 plt.show._needmain = False
    371 # We need to detect at runtime whether show() is called by the user.
    372 # For this, we wrap it into a decorator which adds a 'called' flag.

File /opt/conda/lib/python3.10/site-packages/matplotlib/pyplot.py:342, in switch_backend(newbackend)
    339 # have to escape the switch on access logic
    340 old_backend = dict.__getitem__(rcParams, 'backend')
--> 342 module = importlib.import_module(cbook._backend_module_name(newbackend))
    343 canvas_class = module.FigureCanvas
    345 required_framework = canvas_class.required_interactive_framework

File /opt/conda/lib/python3.10/importlib/__init__.py:126, in import_module(name, package)
    124             break
    125         level += 1
--> 126 return _bootstrap._gcd_import(name[level:], package, level)

File <frozen importlib._bootstrap>:1050, in _gcd_import(name, package, level)

File <frozen importlib._bootstrap>:1027, in _find_and_load(name, import_)

File <frozen importlib._bootstrap>:992, in _find_and_load_unlocked(name, import_)

File <frozen importlib._bootstrap>:241, in _call_with_frames_removed(f, *args, **kwds)

File <frozen importlib._bootstrap>:1050, in _gcd_import(name, package, level)

File <frozen importlib._bootstrap>:1027, in _find_and_load(name, import_)

File <frozen importlib._bootstrap>:1004, in _find_and_load_unlocked(name, import_)

ModuleNotFoundError: No module named 'ipympl'

Somehow we need to have ipyml, at least, installed in the container.

wangyinz commented 6 months ago

I just added that in https://github.com/mspass-team/mspass/commit/0b4b6a7e99297f13162090bae8f0303fb775e042