Skip to content

Releases: raphaelquast/EOmaps

EOmaps v5.2

24 Nov 19:49
5eeb2fd

Choose a tag to compare

A new minor releases with a lot of bugfixes and some awesome usability upgrades.

🌳 New

Some internals of EOmaps have been re-structured to make it easier to add Maps-objects to existing matplotlib-figures!
Check the docs for more details: 🍱 Adding Maps to existing figures

f = plt.figure()
ax = f.add_subplot(211)
m = Maps(f=f, ax=212)

🌦️ Changes

💧 General

  • When using m.savefig(dpi=...) with the plot-shapes "shade_points" or "shade_raster" the shading-pipeline is now automatically adjusted to reflect the dpi of the saved figure (e.g. exporting higher dpi figures will also result in more detailed shading of the data).

  • The 🧰 Companion-Widget has some new functionalities! (e.g. basic click/pick callbacks)

💧 Syntax

  • Maps(gs_ax=...) has been re-named to Maps(ax=...)
  • ❗ Usage of the m.figure.<...> accessor is depreciated!
    • Objects are now directly accessible via m.f, m.ax, m.coll and m.colorbar.ax_cb m.colorbar.ax_cb_plot

💧 Updates for keypress callbacks

  • keypress callbacks are now triggered irrespective of the mouse-position (as long as the figure is active)
  • It is now also possible to create callbacks that trigger on any key by using key=None.
    (the actually used key is passed to the callback via the key kwarg)

💧 Updates for layer sliders

  • There's a new function slider.set_layers() to updates the layers targeted by an existing slider
  • The slider-label now shows the currently visible layer-name in red if the active layer is not targeted by the slider

💧 Updates for logos

  • It is now possible to fix the logo-position relative to the map with m.add_logo(fix_position=True)
    (the default is False so that logos can be re-positioned with the layout-editor!)
  • Checkout the new 👽 logos section in the docs for more details!

🔨 Fixes

  • fix issues when adding Maps-objects to existing figures
  • fix issues when setting the map-extent to the data-extent
  • speed up opening datasets with the companion widget (avoid scaling to retrieve info)
  • allow adding MapsGrid objects to existing figures
  • make "switch_layer" keypress callbacks accept only strings as layer-names
  • update github actions to address depreciation warnings
  • fix registering of transparent colormaps
  • fix issues with boundary-pixels for "raster" shape
  • fix using layer-names that contain double-underscores
  • make sure the figure is closed if Maps is used as context-manager
  • fix handling of long layer-names in companion-widget
  • assign n for shapes based on dataset-size (if not specified explicitly)
  • remove cached background layers of deleted layers
  • adjust shading pipeline on figure resize
  • adjust shading pipeline on m.savefig if dpi is changed
  • fix re-fetching of xyz webmap services if axis size changed
  • fix issues when adding new webmap layers via the companion widget
  • avoid keeping companion-widget "always-on-top"
  • fix logos reset position at next draw event

EOmaps v5.1

12 Nov 13:28
97fd014

Choose a tag to compare

A first minor release for EOmaps v5.x with a lot of bugfixes, some improvements for speed and memory-management and new functionalities for the colorbar!

Make sure to check the new features introduced in EOmaps v5.0 as well!

🌳 New

  • new WebMap service: m.add_wms.DLR_basemaps
  • improved speed and memory-management for very large datasets

🌈 Updates for the colorbar

New convenience function m.colorbar.set_bin_labels() to simplify labeling individual bins of the colorbar with custom names.

Check the 📖 documentation for more details!

  • ... ordinary colorbar (for classified data):
  • ... the colorbar after using m.colorbar.set_bin_labels() to set custom labels at the center of the specified bins

🔨 Fixes

  • allow using (equal-length) 1D datasets for m.set_shape.raster
  • fix close button callback for companion-widget popups
  • fix utility widgets for multiple maps in one figure
  • fix layer assignment for WebMap legends
  • fix providing custom colorbar ticks for classified data
  • fix issues with colorbar tick formatter
  • avoid memory-intense index-creations for very large datasets
  • avoid re-shaping for very large 2D datasets with 1D coordinates
  • add some basic unittests for plotting from files
  • fix colormap usage for classified datasets

EOmaps v5.0

02 Nov 23:29
41c3ca9

Choose a tag to compare

A new major release that brings a lot of very nice features and updates 🥳

❗ (possibly) breaking changes to v4.x ❗

New layer-name convention:

  • All layer-names are now parsed as string!
    (any non-string object passed as layer-name will be converted to string and a warning is shown)

  • The "|" character is used as a separator for multi-layers (see new ⧉ Multi Layers feature below)
    (a layer-name such as "first|second" now represents the combined artists for the layers "first" and "second")

Changes for the colorbar

The implementation of the colorbar has been re-worked and several changes have been introduced:

  • Colorbars are now accessible via m.colorbar
    • Some arguments of m.add_colorbar(...) have changed! Check the docstring for details!
    • The individual colorbar-axes are accessible via m.colorbar.ax_cb and m.colorbar.ax_cb_plot
    • To set the size of the colorbar, use m.colorbar.set_position(...)
    • To remove a colorbar, use m.colorbar.remove()

🌳 New

🧰 Companion widget

Starting with v5.0, EOmaps provides an awesome companion-widget to speed up data-comparisons and analysis.

NOTE: Using the widget is only possible if you use matplotlibs "PyQt5" backend!

  • To open the widget, simply press w on the keyboard while the mouse-pointer is hoovering the map.
  • The ? button on the top left can be used to activate showing help-tooltips if you hoover over the controls explain their functionalities.

📖 Checkout the corresponding section in the docs for more details! 🧰 Companion Widget

✏️ Draw shapes on the map

There is a new functionality to draw simple (geo-coded) shapes on the map!

📖 Checkout the corresponding section in the docs for more details! ✏️ Draw shapes on the map

⧉ Multi Layers

It is now possible to create "multi-layers" which inherit their artists from existing layers.
The layer-name hereby consists of existing layer-names separated by "|".

To show the layers "first" and "second" at the same time, use:

m.show_layer("first|second")
  • If you view a multi-layer, ALL artists from the constituting layers will be shown!
    • E.g.: "first|second|third" will show all artists of the layers "first", "second" and "third"
  • The "vertical stacking order" for plotting is still exclusively determined by the zorder property of the artists!
    • (artists at the same zorder are ordered with respect to the creation-time)
  • It is possible (however rarely useful) to create a Maps object representing multi-layers
    • Its artists will then only be shown if all constituting layers are visible

📖 Checkout the corresponding section in the docs for more details! 🚀 Basics/Layers

🏗️ Updates for the Layout Editor

  • Select (and edit) multiple axes by holding shift while clicking on the axes
  • Scaling the axes-size (with the scroll-wheel or the +/- buttons) now preserves the center of the axis
  • If you hold down control while a colorbar is selected, the scroll wheel (or the +/- buttons) will adjust
    the relative size between the colorbar and the histogram
  • If you hold down h (or v) the scroll-wheel adjusts only the horizontal (or vertical) size of the axes

📖 Checkout the corresponding section in the docs for more details! 🏗️ Layout Editor

🗺️ Set map-extent via OpenStreetMap Nominatim query

  • There is now a method to set the extent of the map via a OSM query.
    m = Maps()
    m.set_extent_to_location("Austria")
    m.add_wms.OpenStreetMap.add_layer.default()

📷 Snapshots for JupyterNotebooks

  • The new m.shapshot() functionality allows you to plot static snapshots of a map
    in Jupyter Notebooks (or in the IPython console) irrespective of the used backend.

👓 Updates for peek-layer callbacks:

  • It is now possible to use transparency when peeking on a layer!
    m.cb.click.attach.peek_layer(layer="some layer", alpha=.5)
  • There's a new option how="full" to overlay another layer on the whole axis
  • The size of the square used for peeking (e.g. how=0.5) is now always with respect to the smallest axis-dimension

... additional new features ...

  • Equi7Grid projections can now be accessed via explicit names (e.g.: Equi7_EU, Equi7_AF...)
  • Any colormap created by EOmaps during runtime is now always registered as a matplotlib colormap
  • It is now possible to add logos to specific layers by using: m.add_logo(layer=...)
  • 🛰️ New WebMap services
    • m.add_wms.OpenStreetMap.OSM_wms
    • m.add_wms.OpenStreetMap.OSM_landuse

Dynamic artists are now layer-sensitive!

  • annotations and markers can now be added to specific layers:
    m.add_annotation(layer=...) and m.add_marker(layer=...)
  • To add dynamic artists on specific layers, simply use m.BM.add_artist(<artist>, layer=...)
    (to make the artist visible on all layers, simply use layer="all")

🌦️ (non-breaking) Changes

  • obsolete arguments radius and radius_crs have been removed from m.set_shape.raster()
  • the default radius for m.set_shape.geod_circles has been set to 1km

🔨 Fixes

  • fix default style kwarg for wms layers
  • remove obsolete shape arguments
  • fix custom args for feature presets
  • fix _on_layer_change actions
  • fix fetching wmts services
  • fix passing kwargs to wms and wmts services added to the active layer
  • fix updating background layers on add/remove of artists
  • fix handling of encoded NetCDF data

EOmaps v4.4.3

06 Oct 15:29
1a6b272

Choose a tag to compare

Just a hotfix release

🔨 fixes

  • fix ImportError for TriMesh when using matpltolib >= 3.6

EOmaps v4.4.2

26 Jul 12:07
e5d203f

Choose a tag to compare

Another bugfix release.

🌳 New

  • Make sure to also have a look at the new features added in EOmaps v4.4!
  • There is now an option to draw a an "outline" on top of the colorbar-histogram with:
    • m.add_colorbar(show_outline=True) (for a black outline with linewidth 1)
    • m.add_colorbar(show_outline=dict(color="b", linewidth=2)) (for a custom outline)

image

🔨 Fixes

  • fix using m.cb.pick callbacks with datasets assigned to the "all" layer
  • raise error if undefined objects are passed to NetCDF and GeoTIFF readers
  • fix using the LayoutEditor to move colorbars with "arrow-keys"
  • fix default styles must be provided as list for wms and wmts services!

EOmaps v4.4.1

21 Jul 20:19
4d88d9f

Choose a tag to compare

A quick bugfix release

🔨 Fixes

  • fix providing kwargs to WebMap services (time, styles etc.)

EOmaps v4.4

A release that introduces 2 new functionalities: m.add_line, m.cb.move and the ability to use keypress-modifiers for callbacks!

🌳 New

🚲 A new method to quickly draw paths on a map!

  • m.add_line(): connect points via geodesic (or straight) lines!
    • specify number of intermediate points per line-segment
      • (alternatively) specify distance between intermediate points for each line-segment
      • checkout the new 🚲 example and the corresponding section in the 📖 documentation!

🛸 New features for callbacks!

👾 Keypress-modifiers

It is now possible to assign multiple callbacks to the same mouse-button and use keyboard-shortcuts
to switch between the assigned callbacks!
(e.g. the callback will only be executed if the corresponding button is pressed on the keyboard)

  • 🌟 simply provide the modifier of choice with the modifier=... argument!

    • e.g.: m.cb.click.attach.annotate(modifier="a") : this callback will only be executed if the "a" key is pressed
  • 🌟 You can make modifiers "sticky" (e.g. to keep them activated after the button is released) by using:

    • m.cb.click.set_sticky_modifiers("a", "b", "c")
    • "sticky modifiers" are assigned separately for click, pick and move callbacks
    • to release a "sticky modifier" press ctrl + <modifier key> or escape
  • checkout the corresponding section in the 📖 documentation!

move callbacks

There's now an explicit container to attach callbacks that are executed
on mouse movement if NO button is clicked

  • NOTE: use m.cb.click.attach... to execute callbacks on mouse-movement if a button is clicked!
    • and set on_motion=False to avoid executing the click-callback on mouse-movements
m = Maps()
m.add_feature.preset.coastline()
m.cb.move.attach.annotate()
m.cb.move.attach.mark(modifier=1, radius=2, radius_crs=4326, fc="none", ec="r")

🌦️ Changes

  • m.cb.click.attach.mark() now uses permanent=False by default

  • 🏞️ NaturalEarth features have been updated

    click for a list of new features
    {
    10m_cultural:  {'admin_0_countries_iso', 'parks_and_protected_lands', 'admin_0_countries_tlc'}
    10m_physical:  {'bathymetry_G_4000', 'graticules_20', 'bathymetry_K_200', 'bathymetry_E_6000', 'graticules_1', 'bathymetry_A_10000', 'bathymetry_F_5000', 'bathymetry_C_8000', 'bathymetry_B_9000', 'bathymetry_L_0', 'bathymetry_H_3000', 'bathymetry_I_2000', 'wgs84_bounding_box', 'bathymetry_J_1000', 'graticules_5', 'bathymetry_D_7000', 'graticules_30', 'graticules_10', 'graticules_15'}
    110m_physical:  {'graticules_15', 'graticules_20', 'graticules_1', 'wgs84_bounding_box', 'graticules_5', 'graticules_30', 'graticules_10'}
    50m_physical:  {'graticules_20', 'graticules_1', 'wgs84_bounding_box', 'graticules_5', 'graticules_30', 'graticules_10', 'graticules_15'}
    }

🔨 Fixes

  • fix sharing boundary and inset-marker properties for inset-maps
  • fix issues with invalid clipping shapes
  • fix issues with geometries that cannot be exploded
  • make sure temporary artists are cleared prior to executing callbacks
  • fix issues with dynamically updated legends and temporary artists
  • fix error when trying to update colorbar-arrows without a colorbar
  • avoid re-fetching WebMap tiles if extent remains the same
  • fix unnecessary re-draws of artists after overlay-actions

EOmaps v4.4

21 Jul 18:11
0d64306

Choose a tag to compare

A release that introduces 2 new functionalities: m.add_line, m.cb.move and the ability to use keypress-modifiers for callbacks!

🌳 New

🚲 A new method to quickly draw paths on a map!

  • m.add_line(): connect points via geodesic (or straight) lines!
    • specify number of intermediate points per line-segment
      • (alternatively) specify distance between intermediate points for each line-segment
      • checkout the new 🚲 example and the corresponding section in the 📖 documentation!

🛸 New features for callbacks!

👾 Keypress-modifiers

It is now possible to assign multiple callbacks to the same mouse-button and use keyboard-shortcuts
to switch between the assigned callbacks!
(e.g. the callback will only be executed if the corresponding button is pressed on the keyboard)

  • 🌟 simply provide the modifier of choice with the modifier=... argument!

    • e.g.: m.cb.click.attach.annotate(modifier="a") : this callback will only be executed if the "a" key is pressed
  • 🌟 You can make modifiers "sticky" (e.g. to keep them activated after the button is released) by using:

    • m.cb.click.set_sticky_modifiers("a", "b", "c")
    • "sticky modifiers" are assigned separately for click, pick and move callbacks
    • to release a "sticky modifier" press ctrl + <modifier key> or escape
  • checkout the corresponding section in the 📖 documentation!

move callbacks

There's now an explicit container to attach callbacks that are executed
on mouse movement if NO button is clicked

  • NOTE: use m.cb.click.attach... to execute callbacks on mouse-movement if a button is clicked!
    • and set on_motion=False to avoid executing the click-callback on mouse-movements
m = Maps()
m.add_feature.preset.coastline()
m.cb.move.attach.annotate()
m.cb.move.attach.mark(modifier=1, radius=2, radius_crs=4326, fc="none", ec="r")

🌦️ Changes

  • m.cb.click.attach.mark() now uses permanent=False by default

  • 🏞️ NaturalEarth features have been updated

    click for a list of new features
    {
    10m_cultural:  {'admin_0_countries_iso', 'parks_and_protected_lands', 'admin_0_countries_tlc'}
    10m_physical:  {'bathymetry_G_4000', 'graticules_20', 'bathymetry_K_200', 'bathymetry_E_6000', 'graticules_1', 'bathymetry_A_10000', 'bathymetry_F_5000', 'bathymetry_C_8000', 'bathymetry_B_9000', 'bathymetry_L_0', 'bathymetry_H_3000', 'bathymetry_I_2000', 'wgs84_bounding_box', 'bathymetry_J_1000', 'graticules_5', 'bathymetry_D_7000', 'graticules_30', 'graticules_10', 'graticules_15'}
    110m_physical:  {'graticules_15', 'graticules_20', 'graticules_1', 'wgs84_bounding_box', 'graticules_5', 'graticules_30', 'graticules_10'}
    50m_physical:  {'graticules_20', 'graticules_1', 'wgs84_bounding_box', 'graticules_5', 'graticules_30', 'graticules_10', 'graticules_15'}
    }

🔨 Fixes

  • fix sharing boundary and inset-marker properties for inset-maps
  • fix issues with invalid clipping shapes
  • fix issues with geometries that cannot be exploded
  • make sure temporary artists are cleared prior to executing callbacks
  • fix issues with dynamically updated legends and temporary artists
  • fix error when trying to update colorbar-arrows without a colorbar
  • avoid re-fetching WebMap tiles if extent remains the same
  • fix unnecessary re-draws of artists after overlay-actions

EOmaps v4.3

05 Jul 18:16
ef52cc6

Choose a tag to compare

A new release that brings some nice updates and an awesome new Layout-Editor!

🌦️ Changes

  • 🍃 utility-widgets now auto-update themselves if new layers are added to the map!
    • to show only a subset of the available layers, use m.util.layer_selector(layers=["layer1", ...])
  • 🍃 coastlines are no longer added by default when creating new layers from files (e.g. NetCDF, GeoTIFF etc.)
    • (use coastlines=True or explicitly call m.add_feature.preset.coastline() to add coastlines!)
  • 🍃 m.add_gdf now allows using a path to a file that can be read with geopandas.read_file instead of providing the geopandas.GeoDataFrame directly
  • ❗ keyword-arguments for m.new_inset_map have changed!
    • edgecolor and linewidth are depreciated and will be removed in next major versions!
    • to set the properties of the boundary-polygon, use m.new_inset_map(boundary=dict(fc="r", lw=1) instead
  • m.cb.dynamic has been removed

🌳 New

⭐ New accessor for classification schemes

The new classification-schemes accessor 🌟 m.set_classify provides autocompletion and proper docstrings!
(you can use it just as you would use m.set_classify_specs)

Just select the scheme you want to use and call it with the relevant parameters:

m = Maps()
m.set_data(...)
m.set_classify.Quantiles(k=5)
m.plot_map(...)

# alternative (old) way to set the classification:   
# m.set_classify_specs(scheme="Quantiles", k=5)

⭐ There's a new 🏗️ Layout Editor to quickly re-arrange the subplots of a figure!

The Layout Editor can be used to quickly re-arrange the position of all axes in the figure.
(works for maps, colorbars, inset-maps, ordinary matplotlib plots etc.)

  • You can save and re-apply a layout with:
    • 🌟m.get_layout(): get the current layout (or dump the layout as a json-file)
    • 🌟m.apply_layout(): apply a given layout (or load and apply the layout from a json-file)
    • 🌟m.edit_layout(filepath=...): enter LayoutEditor and (optionally) save layout as a json-file on exit

To quickly enter/exit Layout Editor, simply use the assigned keyboard-shortcuts:

  • press ALT + L to enter the LayoutEditor mode
  • press ALT + L again or escape to exit the LayoutEditor

Have a look at the new section in the 📖 documentation for more details!

🔨 Fixes

  • fix recognizing the parent layer when initializing utility-widgets from the parent Maps object
  • fix layer-selectors should indicate no active layer if the active layer is not part of the widget
  • updates for inset-maps
  • add fix for reprojection issues with certain projections
  • fix reprojection sometimes masks certain shapes

EOmaps v4.2.3

24 Jun 19:00
df00e0e

Choose a tag to compare

A minor bugfix release.

🌳 new

  • there is now an option to completely disable extension arrows when adding a colorbar
    (e.g. with m.add_colorbar(add_extend_arrows=False))

  • it is now possible to set the "layer" of an inset-map on initialization (e.g. m.new_inset_map(layer="adsf")
    (by default, the "all" layer is used for inset-maps!)

🔨 fixes

  • fix using alpha-transparency with wms and wmts services (e.g. m.add_wms.<service>.add_layer.<layer>(alpha=0.5))
  • fix colors of histogram-bins if the bins extend over more than one colorbar-split
  • fix position of colorbar extension-arrows after using m.subplots_adjust
  • fix appearance of "vertical" colorbar extension arrows

EOmaps v4.2.2

09 Jun 16:13
51b4ffd

Choose a tag to compare

A minor bugfix release.

🌳 new

  • To address issues when plotting 2D raster-data with unsorted coordinates, there is now an option
    to force sorting the data by coordinates prior to plotting with m.plot_map(assume_sorted=False)
    • only works if coordinates are provided as 1D arrays and the data is provided as a 2D array
    • sorting is only relevant for raster and shade_raster shapes (other shapes don't require sorting)
    • by default no sorting is performed!

🌦️ changes

  • The pick-radius used to identify clicked pixels can now be set in 2 ways m.plot_map(pick_distance=...):
    • if a number is provided, it is used as a multiplier for the dataset-radius
      e.g. pick-radius = pick_distance * radius_in_plot_crs)
    • if a string is provided, it is directly used as the pick-radius in units of the plot_crs
      e.g. pick-radius = float(pick_distance)

🔨 fixes

  • ❗ fix using "pick" callbacks with m.set_shape.raster() and 2D input-coordinates
  • make radius-estimation more robust (fallback to nearest-neighbor if 2D estimation fails)
  • fallback to np.inf for pick_distance if radius estimation fails
  • fix delaunay_triangulation does not need to estimate the radius if masked=False
  • fix issues with registering pandas