SheffieldML / GPy

Gaussian processes framework in python
BSD 3-Clause "New" or "Revised" License
2.01k stars 557 forks source link

Error on import due to missing matplotlib dependency #873

Open mgrady3 opened 3 years ago

mgrady3 commented 3 years ago

The setup.py file for gpy declares matplotlib as an optional/extra dependency for the plotting sub-package.

However, due to the way the plotting subpackage is imported in the top-level __init__.py, https://github.com/SheffieldML/GPy/blob/devel/GPy/__init__.py#L15, there does not seem to be a way to import anything from GPy without matplotlib installed. See the example below from a clean pip install of gpy-1.9.9.

$ python -m pip install gpy             
Collecting gpy
  Using cached GPy-1.9.9.tar.gz (995 kB)
Requirement already satisfied: numpy>=1.7 in ./gpy/lib/python3.8/site-packages (from gpy) (1.19.4)
Requirement already satisfied: paramz>=0.9.0 in ./gpy/lib/python3.8/site-packages (from gpy) (0.9.5)
Requirement already satisfied: scipy>=0.16 in ./gpy/lib/python3.8/site-packages (from gpy) (1.5.4)
Requirement already satisfied: six in ./gpy/lib/python3.8/site-packages (from gpy) (1.15.0)
Requirement already satisfied: decorator>=4.0.10 in ./gpy/lib/python3.8/site-packages (from paramz>=0.9.0->gpy) (4.4.2)
Building wheels for collected packages: gpy
  Building wheel for gpy (setup.py) ... done
  Created wheel for gpy: filename=GPy-1.9.9-cp38-cp38-linux_x86_64.whl size=3533673 sha256=6d18e8ce0291905739dab33f5133037f367383b042173c2a50ecdd3d8b288508
  Stored in directory: /home/mgrady/.cache/pip/wheels/6f/42/43/fd9655711b8f8517ffc104cce1b49c7e3ab7bce6a88bb2f0fb
Successfully built gpy
Installing collected packages: gpy
Successfully installed gpy-1.9.9

$ python -c "from GPy.models import GPRegression"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/mgrady/venvs/gpy/lib/python3.8/site-packages/GPy/__init__.py", line 15, in <module>
    from . import plotting
  File "/home/mgrady/venvs/gpy/lib/python3.8/site-packages/GPy/plotting/__init__.py", line 140, in <module>
    change_plotting_library(lib)
  File "/home/mgrady/venvs/gpy/lib/python3.8/site-packages/GPy/plotting/__init__.py", line 18, in change_plotting_library
    import matplotlib
ModuleNotFoundError: No module named 'matplotlib'

I understand that the plotting subpackage has some instructions about settings in a .cfg file that could be used to prevent this import error, but that seems rather cumbersome, and given that the suggestion here, https://github.com/SheffieldML/GPy/blob/devel/GPy/plotting/__init__.py#L22, is to put a file in a User-wide config location, that becomes problematic when you have mutiple projects that may want to use GPy in different ways, i.e. one that cares about plotting and one that does not.

lawrennd commented 3 years ago

Thanks for raising this!

Do you think there's an easy fix?

Very happy to look at a pull request if it's not too difficult to deal with ...

mgrady3 commented 3 years ago

No problem.

From what I can tell, if no user configuration file if present, i.e. ~/.config/GPy/user.cfg, then GPy will fallback to the configuration as specified in the defaults.cfg file, which in this case defaults to library=matplotlib for the [plotting] section of the config:

https://github.com/SheffieldML/GPy/blob/v1.9.7/GPy/util/config.py#L17 https://github.com/SheffieldML/GPy/blob/v1.9.7/GPy/defaults.cfg#L33

So, one option would be to change the default configuration setting in the [plotting] section to library=none. That should make matplotlib truly into an optional dependency. That said, I have not yet tested this to see if there are any further consequences.

I can take a look at what, if anything, would break from that change, but it will take me a bit to get a development environment setup.