Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make matplotlib an optional dependency #2163

Open
esheehan-gsl opened this issue Oct 20, 2021 · 13 comments · May be fixed by #3755
Open

Make matplotlib an optional dependency #2163

esheehan-gsl opened this issue Oct 20, 2021 · 13 comments · May be fixed by #3755
Labels
Area: Plots Pertains to producing plots Type: Feature New functionality

Comments

@esheehan-gsl
Copy link

We're using metpy for some of its interpolate functions in an AWS Lambda function to process some data and send it to a web frontend for visualization. Requiring matplotlib is just increasing the size of our container image and, I think, introducing some security vulnerabilities via ImageMagick (according to the container security scan). It would be really nice if there were a way to disable the visualization tools in metpy so we can use it just for its analytical tools.

@esheehan-gsl esheehan-gsl added the Type: Feature New functionality label Oct 20, 2021
@dopplershift dopplershift added the Area: Plots Pertains to producing plots label Oct 20, 2021
@dopplershift
Copy link
Member

I've had some thoughts like this before, it would be nice to streamline. I think everything should work just fine as long as metpy.plots isn't imported, so it's just a matter of setting the proper packaging metadata. We'd of course have to consider impacts on other users who expect things to work fully out of the box after installing.

Are you building your containers using pip or conda?

@esheehan-gsl
Copy link
Author

I'm using pip.

@dopplershift
Copy link
Member

I think you can achieve what you want today with:

pip install importlib_metadata importlib_resources numpy pandas pint pooch pyproj scipy xarray
pip install --no-deps metpy

Depending on what you're using, you may be able to drop even more of the first line.

I'd love to hear feedback on if that works or something breaks unexpectedly.

@esheehan-gsl
Copy link
Author

Good tip. Thanks! I'll give it a shot.

@esheehan-gsl
Copy link
Author

I think I got this working with

pip install numpy Pint pooch pyproj scipy traitlets xarray
pip install --no-deps metpy

But I discovered something else also depends on Matplotlib (I think Cartopy is the culprit). 🤦🏻‍♂️ 😁

@dopplershift
Copy link
Member

I'm surprised traitlets was necessary since that should only be imported through something down in metpy.plots...

Not sure what's prompting you to install CartoPy--there's not a lot useful about it if you're not using Matplotlib...

@esheehan-gsl
Copy link
Author

The origins of Cartopy in the image are silly and uninteresting, so I won't bore you with the details. I was using it for something I could do with pyproj directly, so it's been removed from the image.

I can run another test to see if I'm able to eliminate traitlets and let you know how it goes.

@dopplershift
Copy link
Member

That would be helpful, thanks!

@esheehan-gsl
Copy link
Author

Alright, I must've messed something up with Docker yesterday because now I'm getting an import error because it can't import matplotlib, even though my script doesn't import matplotlib.

@dopplershift
Copy link
Member

Can you share the full traceback? It'd be good to see because I actually expected that to work.

@esheehan-gsl
Copy link
Author

Looks like it's because I'm using metpy.units.

Traceback (most recent call last):
  File "/var/task/app.py", line 3, in <module>
    from metpy.interpolate import cross_section, log_interpolate_1d
  File "/usr/local/lib/python3.9/site-packages/metpy/__init__.py", line 35, in <module>
    from .xarray import *  # noqa: F401, F403, E402
  File "/usr/local/lib/python3.9/site-packages/metpy/xarray.py", line 31, in <module>
    from .units import DimensionalityError, UndefinedUnitError, units
  File "/usr/local/lib/python3.9/site-packages/metpy/units.py", line 253, in <module>
    units.setup_matplotlib()
  File "/usr/local/lib/python3.9/site-packages/pint/registry.py", line 2189, in setup_matplotlib
    from .matplotlib import setup_matplotlib_handlers
  File "/usr/local/lib/python3.9/site-packages/pint/matplotlib.py", line 12, in <module>
    import matplotlib.units
ModuleNotFoundError: No module named 'matplotlib'

@dopplershift
Copy link
Member

That's good to know. We can consider moving that inside metpy.plots instead.

samthurston pushed a commit to samthurston/MetPy that referenced this issue Feb 11, 2025
Applications that make use of the metpy analytical tools without
the need for visualization may avoid importing matplotlib due to
large import size.

resolves [MetPy#2163](Unidata#2163)
@samthurston samthurston linked a pull request Feb 11, 2025 that will close this issue
@samthurston
Copy link

I'd like to bump this issue, as package management/build systems such as poetry and uv don't have support for excluding nested upstream dependencies, it would be really helpful if the plotting functions were an extra. My use case doesn't seem to have any problem just removing matplotlib from the environment, but my application will not run with matplotlib installed. thanks!

the doc builds on my PR seem to be failing due to a problem with pandas doc server? I'm not sure how to trigger them to re-run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Plots Pertains to producing plots Type: Feature New functionality
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants