Library / SDK
earthlab/earthpy avatar
earthlab/earthpy

EarthPy: plotting and masking raster data without writing the plumbing

A package built to support working with spatial data using open source python

537 stars166 forksPythonBSD-3-Clause

At a glance

What is it?
EarthPy is a Python package that wraps rasterio and geopandas so that common spatial tasks, stacking and cropping bands, masking clouds, plotting false colour, drawing hillshades and computing vegetation indices, are a few lines instead of a page. It is BSD-3-Clause licensed, published on conda-forge and PyPI, and was written to support an earth analytics course.
Who is it for?
Adopt EarthPy if you work with satellite raster data in Python and are tired of assembling plot and mask boilerplate, especially in a teaching context where the code has to be readable. Skip it if you already have a well tested workflow in rasterio and geopandas, since the package is a convenience layer over exactly those.
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 68 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 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The argument is about steps, not about capability

EarthPy makes it easier to plot and manipulate spatial data in Python, and the reasoning in the README is about the cost of generality rather than about missing features. Python is a generic programming language designed to support many different applications, and because of that, many commonly performed spatial tasks for science, including plotting and working with spatial data, take many steps of code. EarthPy builds upon the functionality developed for raster data in rasterio and vector data in geopandas and simplifies the code needed to do a specific list of things: stack and crop raster bands from data such as Landsat into an easy to use numpy array, work with masks to set bad pixels such as those covered by clouds and cloud shadows to NA through mask_pixels, plot rgb, colour infrared and other three band combination images with plot_rgb, plot bands of a raster quickly with plot_bands, plot histograms for a set of raster files, create discrete or categorical legends, calculate vegetation indices such as the Normalized Difference Vegetation Index with normalized_diff, and create a hillshade from a digital elevation model. The design was inspired by the raster and sp package functionality available to R users, which tells you the reference point is the R spatial ecosystem rather than another Python package. The project is BSD-3-Clause licensed, published on PyPI and on the conda-forge channel, and it has a Journal of Open Source Software DOI badge and a pyOpenSci review badge, so the project has been through the kind of external scrutiny that academic and open science packages get.

Installing it, and the warning about pip

The install section is short and opinionated. EarthPy can be installed using pip, but the README strongly recommends conda and the conda-forge channel.

bash
$ conda install -c conda-forge earthpy

If you want conda-forge as your default channel there is a two step workflow the README recommends.

bash
$ conda config --add channels conda-forge
$ conda install earthpy

The pip route exists and the README says so, with the reason for the preference stated plainly, that pip can be more prone to spatial library dependency conflicts.

bash
$ pip install --upgrade earthpy

That is a practical warning rather than a preference, since the dependency set in the setup file includes geopandas, rasterio, scikit-image, numpy, matplotlib, requests, keyring and platformdirs, and a solver that picks mismatched binary wheels for a spatial stack is a common and unpleasant experience. Once installed you import it, and the import shown in the README is the plotting module.

python
>>> import earthpy.plot as ep

The package description in the setup file is also worth quoting, since it explains the scope, that it is a set of helper functions to make working with spatial data in open source tools easier, and that the package is maintained by Earth Lab and was originally designed to support the earth analytics education program.

What the first example shows

The quick example after the install section is a plotting call on a numpy array, and it is a good indication of the shape of the API. The array is created with numpy's randint, with a shape of three bands by five by five, and then passed to plot_bands with a list of titles.

python
>>> arr = np.random.randint(4, size=(3, 5, 5))
>>> ep.plot_bands(arr, titles=["Band 1", "Band 2", "Band 3"])
>>> plt.show()

The important detail is what the function expects. A three dimensional array with bands on the first axis, which is the numpy convention that a lot of raster code converges on because it lets a band be indexed directly, and the function draws each band as a separate panel with its title. There is no file reading, no CRS handling and no windowing in that call, which is the point of the package's layering: the array in, the picture out, and the geospatial plumbing stays in rasterio and geopandas where the more capable machinery already lives. The example directory in the repository follows the same pattern with one script per documented feature, including plot_raster_stack_crop, plot_stack_masks, plot_rgb, plot_hist_functionality, plot_draw_legend_docs, plot_calculate_classify_ndvi and plot_dem_hillshade, and the documentation publishes them as a vignette gallery so each of the listed capabilities has a worked example rather than a signature.

The io module, and why an education package has one

EarthPy also has an io module, and the two things it does are worth separating. The first is quickly accessing pre-created data subsets used in the earth-analytics courses hosted on earthdatascience.org, and the second is downloading other datasets that the user may want in their workflows. The first is the more interesting one, because it is a data access service rather than a plotting convenience, and it explains why the package pulls in requests, keyring and platformdirs. The keyring and platformdirs dependencies are for storing credentials in the operating system keychain and for locating the right configuration directory per platform, which is what a downloader that can reach an authenticated data service needs. This is the design decision that separates EarthPy from a thin plotting wrapper, and it is also the part that makes the package less of a pure library and more of a workflow tool, since a teaching package needs to hand students data they can open without an account, and a research package needs to fetch the datasets a workflow refers to. The repository backs this with an example-data/ directory at the top level, and the setup file ships that data as package data, with example-data entries for json and tif files, so the example datasets travel with the installed package rather than needing a separate download.

The repository shows a project in transition

The release history is the interesting part of the repository state. The most recent release is v1.0.0 with the title AppEEARS API, dated 2026-10-02, and before that v0.10.1 with the title Verbose-only logging from 2025-09-10, and v0.10.0 titled Further API support from 2025-05-19. So the project crossed a major version boundary in 2026, and the setup file declares version 1.0.0 to match. The last push to the repository was on 2026-08-16, and the repository is not archived. The tree shows a conventional and careful project layout, with a ci/ directory, a docs/ directory, an examples/ directory, a scripts and dev-requirements.txt, an environment.yml, a readthedocs.yml, a pyproject.toml that configures black with a line length of 79, a setup.py alongside setup.cfg, a .pre-commit-config.yaml, a .zenodo.json for archiving, a paper.md with a paper.bib for citation, and a CHANGELOG.rst, CONTRIBUTING.rst, CONTRIBUTORS.rst and CODE_OF_CONDUCT.rst. The two build systems, pyproject.toml for black and setup.py for packaging, are a transitional artefact rather than a design choice, and the README still shows a Travis build badge next to an AppVeyor one, both of which are services that have been superseded by GitHub Actions, so the badge set is older than the release history. The active maintainers are named in the README, Nathan Korinek and Elsa Culler, with the latter also listed as the maintainer in the setup file, and a long contributor list that the README admits is out of date.

Where EarthPy is the wrong choice

The first limit is that this is a convenience layer over two libraries that already do the work, so if you have a working rasterio and geopandas pipeline, EarthPy is another dependency to keep current, and a layer that only wraps is a layer that can lag behind the thing it wraps when the underlying API changes. The second is the education origin, which shows in the design. The functions are shaped for a course, with single-purpose calls like plot_bands and mask_pixels rather than a composable object model, and that is exactly what a student needs and exactly what a library author with a large pipeline does not, since a wrapper that returns a matplotlib axis rather than a data structure gives you less to build on. The third is the dependency resolution risk the README itself raises, since a spatial stack installed with pip rather than conda is a recurring source of binary wheel conflicts, and that friction lands on every new user rather than on one unlucky person. The fourth is the version numbering, where 0.10 to 1.0 with an AppEEARS API addition in between suggests recent churn in the io layer, and a package whose download and fetch surface is changing fastest is the part most likely to break. And the fifth is scope: this is plotting and light manipulation of rasters and vectors, not an analysis library, so a workflow that needs classification, zonal statistics or terrain analysis is still going to write that code itself.

Editorial conclusion

Adopt EarthPy if you work with satellite raster data in Python and are tired of assembling plot and mask boilerplate, especially in a teaching context where the code has to be readable. Skip it if you already have a well tested workflow in rasterio and geopandas, since the package is a convenience layer over exactly those. Verify first that your conda environment can resolve the geospatial stack without conflicts, which the README warns about, and that the maintenance situation matches your expectations, since the project version numbers have jumped from 0.10 to 1.0 across a short span.

Frequently asked questions

What does EarthPy simplify compared to using rasterio and geopandas directly?

It wraps the functionality of those two libraries so that stacking and cropping raster bands into a numpy array, masking bad pixels such as cloud cover to NA, plotting rgb and false colour images, drawing discrete legends, computing vegetation indices such as NDVI and creating hillshades from a digital elevation model each take a few lines. The design was inspired by the raster and sp packages available to R users.

How should EarthPy be installed and why does the README prefer conda?

The README strongly recommends conda with the conda-forge channel, either with conda install -c conda-forge earthpy or by setting the channel as the default with conda config --add channels conda-forge. It notes that pip can be more prone to spatial library dependency conflicts, though pip install --upgrade earthpy is supported.

What does the EarthPy io module do?

It has two purposes, quickly accessing pre-created data subsets used in the earth-analytics courses hosted on earthdatascience.org, and downloading other datasets for use in a workflow. The package also ships example data with the installation, and the keyring and platformdirs dependencies exist so credentials can be held in the operating system keychain and platform configuration located correctly.

Official sources

  1. earthlab/earthpy on GitHub
  2. License: BSD-3-Clause
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/earthlab-earthpy.svg)](https://hysenlabs.com/projects/earthlab-earthpy)

Was this useful?