MetPy: weather calculations that plug into numpy instead of wrapping them
MetPy is a collection of tools in Python for reading, visualizing and performing calculations with weather data.
At a glance
- What is it?
- MetPy is a Python collection for reading, visualising and calculating with weather data, built to give GEMPAK-style capability to researchers, educators and anyone scripting a weather analysis, with the difference that the derived quantities are ordinary functions you can pull out and reuse. It is BSD-3-Clause, requires Python 3.11 or later, and is distributed on PyPI and conda-forge.
- Who is it for?
- MetPy is worth adopting for anyone who scripts weather analysis, because the derived quantities are plain functions over numpy and xarray rather than a proprietary data model, so a calculation can be lifted out of a plotting script and reused.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The design goal is to be the Python equivalent of GEMPAK and NCL
The philosophy section says more about the project than the feature list does.
The space MetPy aims for is GEMPAK, and maybe NCL, like functionality, in a way that plugs easily into the existing scientific Python ecosystem of numpy, scipy and matplotlib. Then it describes what an average GEMPAK script for a weather map does: read data, calculate a derived field, show it on a map or a skew-T. Three steps, and the second one is the interesting one.
The stated benefit over GEMPAK is that it should be easier to use these routines for any meteorological Python application, which means making it easy to pull out the LCL calculation and just use that, or to reuse the skew-T with your own data code. That is the whole architectural commitment in one sentence. A meteorological library is normally a closed world with its own file formats, its own grid conventions and its own plotting conventions, and using one calculation from it means adopting all of it. MetPy's position is that the calculations should be ordinary functions over ordinary arrays.
The audience is stated the same way. The intended audience is that of GEMPAK, meaning researchers, educators and anyone wanting to script up weather analysis. It does not even have to be scripting, since all Python meteorology tools are hoped to be able to benefit from MetPy. And the ambition is stated in the other direction too, to be the meteorological equivalent of the audience of scipy, scikit-learn and scikit-image.
That goal is why the project prides itself on being well documented and well tested, so that ongoing maintenance is manageable, and it is also why the repository carries a benchmarks/ directory, a conftest.py and a tools/ directory.
Semantic versioning with a stated compatibility promise
The versioning policy is described in two sentences, and it is worth reading carefully because it is a commitment rather than a label.
MetPy follows semantic versioning in its version number, which means any MetPy 1.x release will be backwards compatible with an earlier 1.y release. The README then defines backward compatible in a specific way: correct code that works on a 1.y version will work on a future 1.x version. The word correct is doing the work, since it excludes code that relies on undefined behaviour or that was already broken.
The releases reflect that. The version history shows v1.7.1 from 2025-08-29, v1.7.0 from 2025-04-30 and v1.6.3 from 2024-08-26, and the last push was on 2026-10-13. The project is not archived and the repository is active, so the compatibility promise is being maintained on a codebase that is still moving.
There is one more promise in the README, and it is about documentation rather than code. MetPy also prides itself on being well-documented and well-tested, so that ongoing maintenance is easily manageable. In a scientific library, that claim is load bearing. The reason is not tidiness, it is that a weather calculation that is quietly wrong produces a plausible sounding number, and a plausible sounding wrong number is more dangerous than an exception. Documentation and tests are the defence against that, and the coverage badge in the README is a claim about that defence.
The project is BSD-3-Clause, which is the permissive licence most of the scientific Python stack uses, and the classifiers in the project metadata label it as Development Status 5 - Production/Stable.
The dependency list explains the unit system requirement
The dependencies are the interesting part of the manifest, because one of them changes how you write code against the library.
The required set is matplotlib 3.7.0 or later, numpy 1.25.0 or later, pandas 2.1.0 or later, pint 0.22 or later, pooch 1.2.0 or later, pyproj 3.4.0 or later, scipy 1.10.0 or later, traitlets 5.1.0 or later and xarray 2022.6.0 or later. The README's own dependency list names Numpy, Scipy, Matplotlib, Pandas, Pint and Xarray as the other required packages, and calls pyproj an optional dependency used with cross sections, grid spacing calculation and the GiniFile interface.
There is a discrepancy between the two lists, and it is not small. The manifest makes pyproj a hard requirement while the README describes it as optional, and the manifest adds pooch and traitlets which the README does not mention at all. For anyone building a reproducible environment, the manifest is the one that gets installed, so the README's dependency list is the one to treat as approximate.
Pint is the reason to look twice. Pint is a units library, and a units library in the required dependencies means MetPy does not accept bare floats for a pressure or a temperature, or if it does, it does so deliberately rather than by omission. A meteorological calculation chain mixes temperatures in Kelvin and Celsius, pressures in hPa and Pa, and distances in metres, and the unit mistakes that produce are the kind that do not raise an exception. Making units part of the interface pushes that class of error into the type system rather than into a review checklist.
Then there is pooch, which is the file fetching and caching library, and its presence tells you the project downloads sample data on demand rather than shipping it in the wheel. The staticdata/ directory at the repository root is where the reference data lives, and it is that data the test extras need, which the manifest explains with a comment about not being able to read its own test data without extras.
The extras split the package into four install shapes
The optional dependencies are where the packaging design becomes clear, because the project offers four ways to install itself.
The doc extra pulls in myst-parser, sphinx, sphinx-gallery, sphinx-design and the pydata-sphinx-theme, and it includes metpy[examples], which means building the documentation requires the examples extra as well. The examples extra adds geopandas 0.6.0 or later and in turn metpy[extras]. The test extra adds netCDF4, packaging, pytest, pytest-mpl and vcrpy 4.3.1 or later, and the comment in the manifest explains why it is needed: if you try to test without extras, you cannot read our own test data.
The extras extra is the interesting one, and it holds cartopy 0.21.0 or later and dask 2020.12.0 or later among its entries. Cartopy is the map projection and basemap drawing library, and dask is the parallel execution framework, so the extras are the two things that turn MetPy from a calculation library into a plotting and scale-out story. The chain from doc to examples to extras is a dependency cascade, and it means a contributor who wants the cartopy examples has to install the extras as well.
vcrpy in the test extra is a detail that explains the testing approach. VCR records and replays HTTP interactions, which is how a test suite can exercise code that fetches real data from a remote server without depending on that server during a test run. Combined with the pooch dependency and the staticdata/ directory, the picture is of a library whose tests need real meteorological files and real network access to the source of those files, cached and recorded so the suite stays deterministic.
pytest-mpl is also worth noting, since it is the plugin that compares generated figures against reference images, which is how a plotting library tests that its output still looks right.
An xarray backend entry point is the integration point with modern data stacks
One line in the manifest describes how MetPy meets the rest of the scientific Python world.
[project.entry-points."xarray.backends"]
gini = "metpy.io.gini:GiniXarrayBackend"This registers a GIN file format reader as an xarray backend, which means a GIN file can be opened through the xarray interface rather than through a MetPy-specific loader. That is a bigger statement than it looks. Xarray is the data model most of the current scientific Python ecosystem shares, with labelled dimensions, coordinates and attributes, and a library that only exposes its own data structures has to be converted at every boundary. Registering as a backend puts MetPy inside the xarray convention instead of beside it.
The GIN format is the one that the README also calls out as the reason pyproj matters, since the GiniFile interface is listed as one of the places where geographic projections are used. GINI is the format used for the gridding and mosaicking of radar and satellite imagery, and the repository has a staticdata/ directory and an examples/remote/ directory, which suggests the library can also fetch and open remote products.
The examples directory is where the scope of the library becomes concrete. There is examples/Advanced_Sounding.py and examples/Advanced_Sounding_With_Complex_Layout.py for the sounding and skew-T workflow, examples/Four_Panel_Map.py, examples/cross_section.py, examples/isentropic_example.py, examples/meteogram_metpy.py, examples/sigma_to_pressure_interpolation.py, examples/XArray_Projections.py, and directories for calculations, formats, gridding, plots and remote data. The examples directory also has its own README.txt.
The file names describe a set of derived quantities that are the reason people reach for a meteorological library at all: lifting condensation level, isentropic surfaces, cross sections, sigma to pressure interpolation. A team that needs one of those as a number rather than a picture can call it directly, which is exactly the separation of concerns the philosophy section asks for.
Where MetPy is the wrong tool
The limits are the ordinary limits of a scientific library, and they are worth stating precisely.
The first is that MetPy is not a forecasting system. It calculates from data you give it and draws what you ask it to draw. It does not ingest live observations, it does not run a numerical weather model, and it does not schedule anything. A team looking for a replacement for an operational forecasting workflow will find a calculation and plotting library, and the surrounding system is still theirs to build.
The second is the dependency weight. The base install pulls in numpy, scipy, pandas, matplotlib, pint, xarray, pooch, pyproj and traitlets. That is a heavy but ordinary scientific stack, and it is fine in an environment that already has it. It is not fine in a small container that only needs one function, such as a service that converts a sounding to a parcel profile, where the alternative is to copy the few equations you need and skip the dependency graph. The extras make it worse, since cartopy and dask are large.
The third is the Python floor. The README says Python 3.11 or later is supported, and the project metadata repeats it as requires-python >= 3.11 while listing classifiers for 3.11 through 3.14. A team on an older runtime cannot use the current release, and the README does not describe a maintenance branch for older versions.
The fourth is the domain. MetPy is a meteorological library, and its units, its conventions and its vocabulary assume atmospheric science. It is not a general units and quantities library that happens to include weather, and it is not a general plotting library with weather support. If your requirement is a unit-aware physics library with no meteorology in it, pint is the dependency to reach for directly, and the rest of the MetPy dependency list is overhead.
One last point about maintenance, since it affects a long-lived pipeline. The last push was on 2026-10-13, and the last release was v1.7.1 on 2025-08-29, so the repository is moving faster than the tags. The compatibility promise covers 1.x releases, and that promise is what makes it reasonable to pin a version and upgrade on your own schedule rather than tracking main.
Editorial conclusion
MetPy is worth adopting for anyone who scripts weather analysis, because the derived quantities are plain functions over numpy and xarray rather than a proprietary data model, so a calculation can be lifted out of a plotting script and reused. It is the wrong tool for operational forecasting on its own, since it does not ingest live observations or run a model cycle, and it is the wrong tool for a script that must run on Python 3.10 or older, because the supported floor is 3.11. Before installing, read the installation guide for the conda and pip paths, and check whether the optional extras you need, such as cartopy or dask, are worth pulling in, since the base install already requires numpy, scipy, pandas, matplotlib, pint and xarray.
Frequently asked questions
What is MetPy used for?
MetPy is a collection of tools in Python for reading, visualizing and performing calculations with weather data, covering soundings, skew-T plots, cross sections, isentropic surfaces and gridding, with the aim of giving GEMPAK-style functionality to anyone scripting weather analysis in Python.
How do I install MetPy?
MetPy is distributed on PyPI and on conda-forge, and the README points to the installation guide for the full details. The required dependencies are matplotlib, numpy, pandas, pint, pooch, pyproj, scipy, traitlets and xarray, and Python 3.11 or later is required.
Is MetPy's API stable between minor versions?
Yes. MetPy follows semantic versioning, and the README states that any 1.x release is backwards compatible with an earlier 1.y release, meaning correct code that works on a 1.y version will work on a future 1.x version.
What are the optional extras in MetPy for?
The doc extra builds the documentation and pulls in the examples extra, which adds geopandas and in turn the extras extra, which contains cartopy and dask. The test extra adds netCDF4, pytest, pytest-mpl and vcrpy, and the manifest notes that without extras you cannot read the project's own test data.
How does MetPy work with xarray?
MetPy registers a GIN file reader as an xarray backend through the xarray.backends entry point, pointing at metpy.io.gini:GiniXarrayBackend, so GIN files can be opened through the xarray interface rather than a MetPy-specific loader.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/unidata-metpy)Was this useful?