Releases: raphaelquast/EOmaps
EOmaps v3.3
A release with some nice new features and a lot of usability updates and fixes.
❗ note that there is a breaking change compared to <v3.2 (only affecting the ambiguous "layer" kwarg of dynamic artists (see 🌦️ changes below for details) )
🌳 NEW
(⭐: new feature, 🍃: new functionalities for existing features)
- ⭐ There's a new pre-defined WebMap service:
m.add_wms.GEBCOthat provides nice underwater topography (https://www.gebco.net/) - ⭐ Theres a new function
m.redraw()that can be used to force a re-draw of the entire figure - ⭐ shortcuts for
mg.redrawandmg.utilhave been added toMapsGrid - 🍃
m.add_wms. ... <layer>.set_extent_to_bbox()now supports a new kwargshrinkwhich can be used to set the extent to a "shrinked" bbox (useful to avoid request-errors for tiles outside the bbox) - 🍃
m.add_colorbarcan now be used to add individual colorbars for different plot-layers
(the colorbars will always reflect the currently displayed layer) - 🍃the
peek_layercallback can now be used to either view one (or more) layers or to overlay one (or more) layers on top of the current background layer. - 🍃 some major improvements have been implemented for fetching WebTiles from xyz-TileServer links.
m.add_wms.get_servicenow supports using customwms,wmts,restAPIorxyzservices
🌦️ changes
- the ambiguous (and misleading)
layerkwarg has finally been removed from dynamic artists.
(note this "layer" was NOT referring to the actual plot-layer but to the stacking of dynamic artists!)layernow always refers to the background layer name and not to the stack-order of dynamic artists!- ❗ the plot-order of multiple artists on the same layer is now determined by matplotlib's
zorderproperty.
- ❕ old:m.cb.click.attach.mark(layer=5)➡️ new:m.cb.click.attach.mark(zorder=5)
- ❕ old:m.cb.click.attach.annotate(layer=5)➡️ new:m.cb.click.attach.annotate(zorder=5)
- ❕ old:m.BM.add_artist(art, layer=5)➡️ new:m.BM.add_artist(art)+art.set_zorder(5) - all examples have been updated accordingly
🔨 fixes
- fix _onrelease() missing 1 required positional argument
- fix issues with
nbaggandipymplbackends (e.g. jupyter notebooks) - fix
plt.showshould only be called if we're in an interactive backend! - fix some issues with the scalebar and colorbar
- re-work of
draggable_axes - fix maxzoom for stamen_watercolor layer
EOmaps v3.2
A release with some nice new features and a lot of fixes & improvements.
... Note: many parts of the 📚 documentation have been updated with small code-examples and images!
🌳 New
- ⭐
m.add_annotationandm.add_markernow support adding multiple objects in one go! - ⭐ raster-shading with datashader now supports 2D arrays for values and coordinates (e.g. curvilinear QuadMeshes)
- ⭐ there's a new function
m.show_layer(name)that provides a shortcut for switching the currently displayed layer - ⭐ layer-names can now be arbitrary strings! (e.g.
Maps(layer=...)orm.plot_map(layer=...))- ❗ The layer-name
"all", has a special meaning: all features on this layer will be visible in ALL other layers!
- ❗ The layer-name
⭐ 🦜 Utility widgets !
EOmaps now has a slot for utility widgets that provides some nice tools to simplify common tasks.
- Utilities are accessible via
m.util.<...>
At the moment, there are 2 utilities that simplify switching between layers:
- ⭐
m.util.layer_selector(): get a "legend-like" object with buttons that can be used to switch between layers - ⭐
m.util.layer_slider(): get a slider that can be used to switch between layers
Checkout the 🦜 Utility widgets section in the docs and the updated example: 🛰 WebMap services and layer-switching
⭐🌈 Updates for the scalebar
The scalebar has been re-worked for a much improved "out-of-the-box" usability.
- By default, the scalebar is now automatically re-scaled on pan/zoom events based on the current extent of the map.
- the new
autoscale_fractionargument can be used to set the relative size of the (autoscaled) scalebar - the new
auto_positionargument can be used to set the position targeted for automatic re-positioning on pan/zoom events.
- the new
- The background patch is now automatically scaled to enclose the labels.
- When dragging the scalebar with the mouse, it is now immediately released if you release the mouse-button.
m.add_scalebar() # get a scalebar that autoscales itself on pan/zoom events
m.add_scaleblar(scale=10000) # get a scalebar with a fixed segment-separation of 10km🌦️ changes
- some changes to
m.new_layer:- It now supports the additional
layerkwarg - ❗ By default ONLY the "plot-shape" is now copied to the new layer.
- this avoids side-effects from unintentional copying of plot-specs (
vminvmaxetc.) - you can still copy plot-specs by using
m.new_layer(copy_plot_specs=True)
- this avoids side-effects from unintentional copying of plot-specs (
- It now supports the additional
Maps.from_fileandMaps.read_fileandm.new_layer_from_filenow support using already opened NetCDF and GeoTIFF files
⚙️ fixes
- fix treatment of colorbar orientation in
m.figure.set_colorbar_position - fix reprojection of wms-layers with a native crs specified as "EPSG:3857"
- fix sorting of layer-names
- avoid identification of pixel-ID if no pick-callback is attached
- fix label-axis should not respond to navigation events
- fix adding multiple markers in one go
- fallback to WSG84 boundary in
wms_layer.set_bbox_to_extent()
EOmaps v3.1.4
a minor bugfix release that introduces a new (optional) kwarg for m.plot_map()
🌳 New
- Checkout the new example! 🧮 Select 1D slices of 2D datasets
(as suggested in #54) - ⭐ There is a new (optional) kwarg
set_extentform.plot_map(set_extent=True)set_extent=True: set the plot-extent to the data extentset_extent=False: keep the plot-extent as it was before
🔨 fixes
- fix
m.new_layer()when parent layer usesshade_rasterorshade_points
(fixes__call__() got an unexpected keyword argument 'glyph') - allow overriding the permanent kwarg in
m.add_annotationnm.add_annotation
EOmaps v3.1.3
... another bugfix release
🌦️ changes
- an AssertionError is now raised if data- and coordinate dimensions do not match
(to avoid treating datasets with equal size but different shape as valid 1D inputs)
🔨 fixes
- fix re-projection of data provided with 1D coordinates and 2D data-values (e.g. raster-data)
- fix treatment of nan-values for datashader plots
- update docs for NaturalEarth features and GeoDataFrames
EOmaps v3.1.2
... some more quick fixes
🔨 fixes
- fix rotation angle of ellipses
- remove unnecessary print command
- fix treatment of plot_specs kwargs (vmin, vmax, cmap etc...) in Maps.from_file
- fix defaultargs in add_gdf
EOmaps v3.1.1
A minor bugfix release
🌦️ changes
- 🚀 major speedup and reduced memory consumption for very large datasets
- new way for indexing picked pixels (uses much less ram with similar performance)
- the
pick_distanceargument ofMaps()now specifies the search-rectangle for identifying picked pixels- a rectangle of
radius * pick_distancexradius * pick_distancearound the center of the clicked pixel is used
- a rectangle of
🔨 fixes
- fix deleting callbacks from within a callback
- fix automatic identification of Equi7Grid crs
- fix treatment of numerical wms-layer names
- fix intersection of gdf with crs domain
- fix Maps.read_file should be a classmethod
- fix deleting data_specs when figure is closed
EOmaps v3.1
🌳 New
⭐ New bindings for the awesome datashader library!
- Particularly useful to speed up plotting of extremely large datasets (>10M datapoints)
- Requires
datashaderto be installed (e.g.conda install -c conda-forge datashader) - To use "datashader" for rendering the map, set the
plot-shapeto:m.set_shape.shade_points(...):
use datashader to "shade" the data with infinitesimal pointsm.set_shape.shade_raster(...):
(only for rectangular datasets with data_crs=plot_crs)
use datashader to "shade" the data as a dynamically updated QuadMesh
⭐ It is now possible to add a Compass (or a North-Arrow) to the map!
- simply use
c = m.add_compass(...) - the compass is dynamically updated on zoom events and can be dragged around with the mouse!

⭐ EOmaps now has some basic readers for common data-types (NetCDF, GeoTIFF, CSV)
- Requires
xarray,rioxarrayandpandas - Use
gdf = m.read_file.NetCDF(...)to read all relevant data - Use
m = Maps.from_file.NetCDF(...)to directly initialize aMaps-object from a file - Use
m2 = m.new_layer_from_file.NetCDF(...)to add a new layer to an existingMapsobject from a file
⭐ Support for Equi7Grid projection
- EOmaps now provides a cartopy-compatible crs for Equi7Grid projections!
- Requires
equi7gridto be installed (e.g.pip install equi7grid)
from eomaps.projections import Equi7Grid_projection
m = Maps(Equi7Grid_projection("EU")⭐ New clipping & re-projection methods for GeoDataFrames
m.add_gdf()andm.add_feature()now have 2 new arguments:reprojectandclip
(useful to avoid re-projection issues):reprojectlets you select between geopandas (="gpd") and "cartopy" for re-projecting the geometriescliplets you select multiple ways for clipping the data prior to plotting- "crs", "crs_bounds", "extent", "gdal_SymmetricDifference", "gdal_Intersection" and "gdal_Difference"
🌦️ changes
- The pixel-radius is now estimated using a more robust method if no explicit radius is provided.
- it's based on the median of the nearest-neighbour distances for the first 100k datapoints
- the number of datapoints used to estimate the radius can be adjusted by setting
m.set_shape.radius_estimation_range
- The
titleargument ofm.set_plot_specsis now depreciated... usem.ax.set_title()instead!
⚙️ fixes
- fix
MapsGridcrs-specifications with pyproj andnumpy-dtypes - fix skipping re-projection if "in-crs" == "plot_crs"
- fix
MapsGridhas no attributepreferred_wms_service - fix 'radius' estimation for shapes that do not explicitly require a radius
- fix background-layers need to be re-fetched if the figure canvas is resized
- clear data from memory if the figure is closed
- fix masking of nan-values prior to plotting
m.add_colorbar()now supports setting the number of bins used to draw the histogram via thehistbinskwarg- make sure that zoom and close callbacks are only attached once to the figure
- fix delayed fetching of RestAPI services
EOmaps v3.0
EOmaps v3.0 comes with a lot of usability improvements and some nice new features!
❗ NOTE: There are breaking changes compared to EOmaps v2.x
... if you used EOmaps before, make sure to take a quick look at the list below!
(or check the examples in the doc which have been updated accordingly)
❗ details on breaking changes with respect to EOmaps v2.x - [click to expand]
-
Removed functions and properties:
m.add_overlay,m.add_coastlines,m.crs_list -
Changed arguments and/or behavior:
Maps,MapsGrid,m.copy,m.plot_map,m.add_gdf,m.add_colorbar -
New functions:
m.new_layer,m.add_feature,m.add_logo,m.cb.pick.highlight_geometry- ❗
m.add_overlayandm.add_coastlineshave been removed in favor ofm.add_feature- ⭐ use
m.add_feature.<category>.<feature>( ... )instead
- ⭐ use
- ❗ the
coastlinesas well as thecolorbarargument form.plot_map()have been removed- ⭐ use
m.add_feature.preset.coastline()orm.ax.coastlines()instead - ⭐ use
m.add_colorbar()after callingm.plot_map()to add a colorbar for an existing map
- ⭐ use
- ❗ the arguments and behavior of
m.copy(...)have changed
(note that most of the time users anyway will want the new ⭐m.new_layer()function)- all arguments of
m.copyare now without the "copy_" prefix, e.g.: "data" instead of "copy_data" etc.
- all arguments of
- ❗ the first argument of
Mapsis now the plot-crs (e.g.Maps(crs=3857)is the same asm.plot_specs.crs=3857)
and additionalkwargsare forwarded to the initialization of the matplotlib-figure (e.g.plt.figure)
- ❗
🌳 New
⭐ the plot coordinate-system is now specified directly on initialization of Maps object
- ❗ NOTE: this replaces
m.set_plot_specs(crs=...)as well asm.plot_specs.crs=... - additional kwargs are passed to the initialization of the
matplotlibfigure
m=Maps(crs=4326, figsize=(10,5))⭐ there's a new function m.new_layer() that simplifies adding new layers to a map
- it simply returns a new
Mapsobject that shares the figure and plot-axes.
⭐ EOmaps now supports multiple ways for providing datasets!
- a single
pandas.DataFramecontaining both values and coordinates (the only option for EOmaps < v2.4.2) - individual
pandas.Seriesfor data-values and coordinates - individual 1D or 2D
numpy.arraysfor data-values and coordinates - individual 1D lists for data-values and coordinates
⭐ The new m.add_feature container provides direct access to ALL NaturalEarth features!
- ❗ NOTE: this replaces
m.add_overlayandm.add_coastlines - autocompletion helps with identifying the relevant NaturalEarth features
- e.g.
m.add_feature.physical_10m.<...feature...>(...)orm.add_feature.cultural_50m.<...feature...>(...)
- e.g.
- with
geopandasinstalled, NaturalEarth features can be interactive too!
(adding static layers works also withoutgeopandas)
# access specific NaturalEarth layers:
m.add_feature.cultural_50m.admin_0_countries(fc="red", ec="k", alpha=0.5)
# there are some presets to quickly add commonly used features
m.add_feature.preset.ocean() # (coastline, land, countries)
# make the layers interactive (requires geopandas)!
m.add_feature.cultural_50m.admin_0_countries(fc="none", ec="k", picker_name="countries")
m.cb.pick["countries"].attach.highlight_geometry(fc="r")⭐ there's a new function m.add_logo that can be used to add images to the map
- particularly useful to add a smal logo in the corner of a plot
⭐ a lot of improvements to m.add_gdf
- it is now possible to pick a geometry based on the closest
"centroids"or based on a"contains"query- with this, picking now also works for lines and points!
# for picking lines and points m.add_gdf(gdf, picker_name="pickername", pick_method="centroids") m.cb.pick["pickername"].attach.<...> # for picking polygons m.add_gdf(gdf, picker_name="pickername2", pick_method="contains") m.cb.pick["pickername2"].attach.<...>
⭐ there's a new pre-defined callback m.cb.pick[<name>].highlight_geometries
- this callback is exclusive to
geopandas.GeoDataFramesand allows highlighting a shape when you click on it!
⭐ m.add_colorbar() can now be used to add colorbars to existing Maps!
- ❗ NOTE: this replaces the old
colorbar-argument ofm.plot_map()
⭐ MapsGrid now supports additional functionalities
- use
MapsGrid(crs=...)to specify the crs
(unique crs for each Maps-objects can be specified by passinglistsordicts) - there are a lot of new convenience-functions to execute actions on all
Mapsobjects on the grid:mgrid.add_feature,mgrid.add_wms,mgrid.add_colorbar,mgrid.set_shape,mgrid.add_logo
⭐ the plot-axis can now be accessed directly via m.ax
⭐ possible crs for plotting are now accessible via Maps.CRS and possible classifiers are accessible via Maps.CLASSIFIERS
🔧 fixes
- fix
m.cb.pick.plotcallback - fix forwarding of event attributes
- treatment of point- or line-like NaturalEarth features
- fix
layerkwarg form.add_gdf - a lot more unittests!
- allow positional arguments for
m.set_data(orm.set_data_specs)
EOmaps v2.4.1
A minor bugfix release
🔧 fixes
- fix nested copying of Maps objects with "connect=True"
- fix
EEA_DiscoMapWMS service - fix toolbar-action check if no toolbar exists
- fix
m.cb.dynamic.indicate_extent()does not show extent right away - ... update some warnings, remove obsolete functions and print-statements
⚙️ updates
- ... a lot of new unittests
- all examples from the doc are run during the unittests
- added tests for WebMap services
- added tests for interactive capabilities (scalebar, draggable axes, etc.)
EOmaps v2.4
🌳 New
- there's a new example in the docs to show how to analyse an underlying database
🌌 Data analysis widgets - interacting with a database
🌻 NEW functionalities for eomaps.MapsGrid !
- It is now possible to use
Mapsobjects alongside ordinary matplotlib axes withMapsGrid!- 2 additional kwargs (
m_initsandax_inits) provide full control over the initialization of the MapsGrid object.
- 2 additional kwargs (
For example:
from eomaps import MapsGrid
mgrid = MapsGrid(2, 2,
m_inits=dict(top_row=(0, slice(0, 2)),
bottom_left=(1, 0)),
ax_inits=dict(bottom_right=(1,1))
)
mgrid.m_top_row # A Maps object whose axis spans over the entire top-row of the grid
mgrid.m_bottom_left # A Maps object with an axis in the bottom left corner of the grid
mgrid.ax_bottom_right # An ordinary matplotlib axis in the bottom right corner of the grid🔨 updates and fixes
- the creation of a colorbar-axes is now omitted in case
plot_mapis called without a dataset - some doc updates
- from now on, a warning to install
geopandasis only shown if a function that actually requires geopandas is called
(e.g.add_overlayandadd_gdf) - it is now possible to partially re-create an already closed figure
- attached callbacks are automatically re-assigned to the newly created figure
- all properties that are not related to the figure object remain unchanged in case the figure is closed
- ... however, any plot-functions (
plot_map,add_marker,add_wmsetc. ) must be called again!
- fix sharing of click events
- disable arrows in colorbar (for now) to ensure that the limits are correct
