ipython / matplotlib-inline

Inline Matplotlib backend for Jupyter
BSD 3-Clause "New" or "Revised" License
19 stars 29 forks source link

Optional dependency on matplotlib? #4

Open mgorny opened 3 years ago

mgorny commented 3 years ago

Just find it a bit weird that mpl isn't listed in install_requires.

martinRenou commented 3 years ago

It's for convenience. IPython has a direct dependency on the matplotlib-inline backend so that the inline backend is always useable inside IPython. But we don't want IPython to have a dependency on Matplotlib, it's something that the user will need to install manually.

mgorny commented 3 years ago

I don't really understand. From what I've tried, attempting to use it results in an ImportError anyway:

$ ipython
Python 3.9.4 (default, May  3 2021, 10:42:13) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.23.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: %matplotlib inline
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-1-9e3324102725> in <module>
----> 1 get_ipython().run_line_magic('matplotlib', 'inline')

/usr/lib/python3.9/site-packages/IPython/core/interactiveshell.py in run_line_magic(self, magic_name, line, _stack_depth)
   2346                 kwargs['local_ns'] = self.get_local_scope(stack_depth)
   2347             with self.builtin_trap:
-> 2348                 result = fn(*args, **kwargs)
   2349             return result
   2350 

<decorator-gen-101> in matplotlib(self, line)

/usr/lib/python3.9/site-packages/IPython/core/magic.py in <lambda>(f, *a, **k)
    185     # but it's overkill for just that one bit of state.
    186     def magic_deco(arg):
--> 187         call = lambda f, *a, **k: f(*a, **k)
    188 
    189         if callable(arg):

/usr/lib/python3.9/site-packages/IPython/core/magics/pylab.py in 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)
    101 

/usr/lib/python3.9/site-packages/IPython/core/interactiveshell.py in enable_matplotlib(self, gui)
   3515         """
   3516         from IPython.core import pylabtools as pt
-> 3517         from matplotlib_inline.backend_inline import configure_inline_support
   3518         gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
   3519 

/usr/lib/python3.9/site-packages/matplotlib_inline/backend_inline.py in <module>
      4 # Distributed under the terms of the BSD 3-Clause License.
      5 
----> 6 import matplotlib
      7 from matplotlib.backends.backend_agg import (  # noqa
      8     new_figure_manager,

ModuleNotFoundError: No module named 'matplotlib'
martinRenou commented 3 years ago

As I said, you need to install Matplotlib manually. IPython should not depend on Matplotlib.

mgorny commented 3 years ago

Sure but I don't understand what's the point of installing matplotlib-inline automatically if it doesn't work.

martinRenou commented 3 years ago

It's for convenience, the inline backend is part of the IPython goodies, it's IPython that provides the matplotlib magic command, even when Matplotlib is not installed.

haampie commented 8 months ago

I don't think it is convenient, cause now the user has to do the task of the dependency resolver to figure out compatible versions.

If you specify the dependency, you can specify compat bounds.

If you don't want to make it a required dep, then at least make it an optional dependency.

ipython[matplotlib] could depend on matplotlib-inline[matplotlib] to finally enforce the matplotlib dependency, and the solver can figure out a compatible version.

martinRenou commented 8 months ago

I don't think it is convenient, cause now the user has to do the task of the dependency resolver to figure out compatible versions.

AFAIK there hasn't be known incompatible versions yet so this issue has not come. But it's true it may come at some point.

Unfortunately there isn't a common way between pip and conda to make optional dependency constraints (also commented here)

martinRenou commented 8 months ago

ipython[matplotlib] could depend on matplotlib-inline[matplotlib] to finally enforce the matplotlib dependency, and the solver can figure out a compatible version.

Maybe @Carreau would have an opinion on this approach?

haampie commented 8 months ago

Unfortunately there isn't a common way between pip and conda to make optional dependency constraints

I'm packaging for spack where you can, but then again, we can just manually define the optional dep whether it's specified or not.

Carreau commented 8 months ago

ipython[matplotlib]

Su re I can add a [matplotlib] dependency. Note that matplotlib should already be a dependency when doing ipython[all].

See https://github.com/ipython/ipython/pull/14362