EOmaps logo

tests codecov       pypi Conda Version       Documentation Status Buy Me A Coffee

DOI: 10.5281/zenodo.6459598


EOmaps - Interactive maps in python!

EOmaps is a Python package to visualize and analyze geographical datasets.

It is built on top of matplotlib and cartopy and aims to provide an intuitive and easy-to-use interface to handle the following tasks:

🔨 Installation

To install EOmaps (and all its dependencies) via the conda package-manager, simply use:

conda install -c conda-forge eomaps

... to get a huge speedup, use mamba to solve the dependencies!

conda install -c conda-forge mamba
mamba install -c conda-forge eomaps

For more information, have a look at the installation instructions or checkout the quickstart guide 🚀 from 0 to EOmaps!

📖 Documentation

Make sure to have a look at the 🌳 documentation 🌳 which provides a lot of examples on how to create awesome interactive maps (incl. 🐍 source code)!

✔️ Citation

Did EOmaps help in your research?
Consider supporting the development and add a citation to your publication!

https://doi.org/10.5281/zenodo.6459598

🚀 Contribute

Found a bug or got an idea for an interesting feature?
Open an issue or start a discussion, and I'll see what I can do!

Interested in actively contributing to the library?


EOmaps example 6 EOmaps example 2
EOmaps example 9 EOmaps example 4
EOmaps example 7 EOmaps example 8
EOmaps inset-maps EOmaps example 3
EOmaps example 9 EOmaps example 4

🌳 Basic usage

Checkout the 🚀 Basics in the documentation!

from eomaps import Maps
import numpy as np
### Initialize Maps object
m = Maps(crs=Maps.CRS.Orthographic(), figsize=(12, 8))

### Add map-features from NaturalEarth
m.add_feature.preset.coastline()
m.add_feature.cultural.admin_0_countries(scale=50, fc="none", ec="g", lw=0.3)

### Add imagery from open-access WebMap services
m.add_wms.OpenStreetMap.add_layer.default()

### Plot datasets
# --- Create some random data
x, y = np.mgrid[-50:40:5, -20:50:3]
data = x + y
# ---
m.set_data(data=data, x=x, y=y, crs=4326) # assign a dataset
m.set_shape.ellipses() # set how you want to represent the data-points on the map
m.set_classify_specs(scheme=Maps.CLASSIFIERS.FisherJenks, k=6) # classify the data
m.plot_map(cmap="viridis", vmin=-100, vmax=100, set_extent=False) # plot the data
m.add_colorbar(hist_bins="bins", label="What a nice colorbar") # add a colorbar

### Use callback functions to interact with the map
#   (NOTE: you can also define custom callbacks!)
# - Click callbacks are executed if you click anywhere on the map
#   (Use keypress-modifiers to trigger only if a button is pressed)
m.cb.click.attach.mark(shape="geod_circles", radius=1e5, button=3)
m.cb.click.attach.peek_layer(layer="layer 2", how=0.4)
m.cb.click.attach.annotate(modifier="a")
# - Pick callbacks identify the closest datapoint
m.cb.pick.attach.annotate()
# - Keypress callbacks are executed if you press a key on the keyboard
#   (using "m.all" ensures that the cb triggers irrespective of the visible layer)
m.all.cb.keypress.attach.switch_layer(layer="base", key="0")
m.all.cb.keypress.attach.switch_layer(layer="layer 2", key="1")

### Use multiple layers to compare and analyze different datasets
m2 = m.new_layer(layer="layer 2") # create a new plot-layer
m2.add_feature.preset.ocean() # populate the layer
# Get a clickable widget to switch between the available plot-layers
m.util.layer_selector(loc="upper center")

### Add zoomed-in "inset-maps" to highlight areas on th map
m_inset = m.new_inset_map((10, 45), radius=10, layer="base")
m_inset.add_feature.preset.coastline()
m_inset.add_feature.preset.ocean()

### Reposition axes based on a given layout (check m.get_layout())
m.apply_layout(
    {'0_map': [0.44306, 0.25, 0.48889, 0.73333],
     '1_cb': [0.0125, 0.0, 0.98, 0.23377],
     '1_cb_histogram_size': 0.8,
     '2_map': [0.03333, 0.46667, 0.33329, 0.5]}
    )

### Add a scalebar
s = m_inset.add_scalebar(lon=15.15, lat=44.45,
                         autoscale_fraction=.4,
                         scale_props=dict(n=6),
                         label_props=dict(scale=3, every=2),
                         patch_props=dict(lw=0.5)
                         )

### Add a compass (or north-arrow)
c = m_inset.add_compass(pos=(.825,.88), layer="base")

### Plot data directly from GeoTIFF / NetCDF or CSV files
#m4 = m.new_layer_from_file.GeoTIFF(...)
#m4 = m.new_layer_from_file.NetCDF(...)
#m4 = m.new_layer_from_file.CSV(...)

🌼 Thanks to