πΈ Callbacksο
How to attach callbacks to a mapο
Callbacks are used to execute functions when you click on a map or press a key on the keyboard**.
There are many useful Pre-defined callbacks, but it is also possible to define Custom callbacks and attach them to the map.
To attach a pre-defined callback to a
Maps
object, use:m.cb.< EVENT CATEGORY >.attach.< CALLBACK NAME >( **kwargs )
To attach a custom callback to a
Maps
object, use:def my_callback(**kwargs): ... m.cb.< EVENT CATEGORY >.attach(my_callback, **kwargs )
The < EVENT CATEGORY >
hereby specifies the event that will trigger the callback:
Callbacks that are executed if you click anywhere on the Map. |
|
Callbacks that identify the nearest datapoint(s) if you click on the map. |
|
Callbacks that are executed if you press a key on the keyboard. |
|
Callbacks that are executed if you move the mouse without holding down a button. |
Callbacks are layer sensitive!
Callbacks are only executed if the layer of the associated Maps
object is visible!
To define callbacks that are executed independent of the visible layer, you have the following possibilities:
Attach the callbacks to the"all"
layer using something like:m.all.cb.click.attach.annotate()
Execute callbacks of an event category independent of the visible layer by setting:m.cb.< EVENT CATEGORY >.set_execute_on_all_layers(True)
from eomaps import Maps
import numpy as np
x, y = np.mgrid[-45:45, 20:60]
m = Maps(Maps.CRS.Orthographic())
m.all.add_feature.preset.coastline()
m.set_data(data=x+y**2, x=x, y=y, crs=4326)
m.plot_map()
m2 = m.new_layer(copy_data_specs=True, layer="second_layer")
m2.plot_map(cmap="tab10")
# get an annotation if you RIGHT-click anywhere on the map
m.cb.click.attach.annotate(xytext=(-60, -60),
bbox=dict(boxstyle="round", fc="r"))
# pick the nearest datapoint if you click on the MIDDLE mouse button
m.cb.pick.attach.annotate(button=2)
m.cb.pick.attach.mark(buffer=1, permanent=False, fc="none", ec="r", button=2)
m.cb.pick.attach.mark(buffer=4, permanent=False, fc="none", ec="r", button=2)
# peek at the second layer if you LEFT-click on the map
m.cb.click.attach.peek_layer("second_layer", how=.25, button=3)
|
![]() |
In addition, each callback-container supports the following useful methods:
|
Attach custom or pre-defined callbacks to the map. |
Remove previously attached callbacks from the map. |
|
|
Accessor for objects generated/retrieved by callbacks. |
Share callback-events between this Maps-object and all other Maps-objects. |
|
Forward callback-events from this Maps-object to other Maps-objects. |
|
Make an artist temporary (remove it from the map at the next event). |
|
Define keys on the keyboard that should be treated as "sticky modifiers". |
|
Set if callbacks should be executed during a toolbar action (e.g. pan/zoom). |
|
If True, callbacks of this container are executed even if the associated layer is not visible. |
Using callbacks with the companion-widgetο
Some of the most commonly used pre-defined callbacks are integrated in the π§° Companion Widget.
peek layer callbacks to interactively compare layers
basic click/pick callbacks to get information on the clicked point

Pre-defined callbacksο
Pre-defined click, pick and move callbacksο
Callbacks that can be used with m.cb.click
, m.cb.pick
and m.cb.move
:
Overlay a part of the map with a different layer if you click on the map. |
|
Add a text-annotation to the plot at the position where the map was clicked. |
|
Draw markers at the location where the map was clicked. |
|
Print details on the clicked pixel to the console. |
Callbacks that can be used with m.cb.click
and m.cb.pick
:
Successively collect return-values in a dict. |
|
Remove all temporary and permanent annotations from the plot. |
|
Remove all temporary and permanent annotations from the plot. |
Callbacks that can be used only with m.cb.pick
:
Load objects from a given database using the ID of the picked pixel. |
|
Temporarily highlite the picked geometry of a GeoDataFrame. |
Pre-defined keypress callbacksο
Callbacks that can be used with m.cb.keypress
Change the default layer of the map. |
|
Fetch (and cache) layers of a map. |
Custom callbacksο
Custom callback functions can be attached to the map via:
m.cb.< EVENT >.attach(< CALLBACK FUNCTION >, **kwargs )
The < CALLBACK FUNCTION >
must accept the following keyword-arguments:
ID
: The ID of the picked data pointThe index-value if a
pandas.DataFrame
is used as dataThe (flattened) numerical index if a
list
ornumpy.array
is used as data
ind
: The (flattened) numerical index (even ifpandas.DataFrames
are used)pos
: The coordinates of the picked data point in the crs of the plotval
: The value of the picked data pointval_color
: The color of the picked data point
from eomaps import Maps
def some_callback(custom_kwarg, **kwargs):
print("\n-------------------------------------------------------")
print("The value of 'custom_kwarg' is", custom_kwarg)
print("The position of the clicked pixel in plot-coordinates is", kwargs["pos"])
print("The dataset-index of the nearest datapoint is", kwargs["ID"])
print("The data-value of the nearest datapoint is", kwargs["val"])
print("The color of the nearest datapoint is", kwargs["val_color"])
print("The numerical index of the nearest datapoint is", kwargs["ind"])
# attaching custom callbacks works completely similar for "click", "pick", "move" and "keypress"!
m = Maps()
m.set_data([1, 2, 3], [10, 20, 30], [10, 20, 30])
m.plot_map()
m.cb.pick.attach.annotate()
m.cb.pick.attach(some_callback, button=1, custom_kwarg=123)
Note
β for click callbacks,
ID
,ind
,val
andval_color
are set toNone
!β for keypress callbacks,
ID
,ind
,pos
,``val`` andval_color
are set toNone
!
For better readability it is recommended that you βunpackβ used arguments like this:
from eomaps import Maps
def cb(ID, val, **kwargs):
print(f"the ID is {ID} and the value is {val}")
m = Maps()
m.set_data([1, 2, 3], [10, 20, 30], [10, 20, 30])
m.plot_map()
m.cb.pick.attach(cb)
Keypress modifiersο
It is possible to trigger pick
, click
or move
callbacks only if a specific key is pressed on the keyboard.
This is achieved by specifying a modifier
when attaching a callback, e.g.:
from eomaps import Maps
m = Maps()
m.add_feature.preset.coastline()
# a callback that is executed if NO modifier is pressed
m.cb.move.attach.mark(radius=5)
# a callback that is executed if 1 is pressed while moving the mouse
m.cb.move.attach.mark(modifier="1", radius=10, fc="r", ec="g")
# a callback that is executed if 2 is pressed while moving the mouse
m.cb.move.attach.mark(modifier="2", radius=15, fc="none", ec="b")
To keep the last pressed modifier active until a new modifier is activated,
you can make it βstickyβ by using m.cb.move.set_sticky_modifiers()
.
βSticky modifiersβ remain activated until
A new (sticky) modifier is activated
ctrl + <current (sticky) modifier>
is pressedescape
is pressed
NOTE: sticky modifiers are defined for each callback method individually! (e.g. sticky modifiers are unique for click, pick and move callbacks)
from eomaps import Maps
m = Maps()
m.add_feature.preset.coastline()
# a callback that is executed if 1 is pressed while clicking on the map
m.cb.click.attach.annotate(modifier="1", text="modifier 1 active")
# a callback that is executed if 2 is pressed while clicking on the map
m.cb.click.attach.annotate(modifier="2", text="modifier 2 active")
# make the modifiers 1 and 2 sticky for click callbacks
m.cb.click.set_sticky_modifiers("1", "2")
# note that the modifier 1 is not sticky for move callbacks!
# m.cb.move.set_sticky_modifiers("1") # (uncomment to make it sticky)
m.cb.move.attach.mark(radius=5)
m.cb.move.attach.mark(modifier="1", radius=5, fc="r")
Picking N nearest neighboursο
[requires EOmaps >= 5.4]
By default pick-callbacks pick the nearest data point with respect to the click position.
To customize the picking-behavior, use m.cb.pick.set_props()
. The following properties can be adjusted:
n
: The (maximum) number of data points to pick within the search-circle.search_radius
: The radius of a circle (in units of the plot-crs) that is used to identify the nearest neighbours.pick_relative_to_closest
: Set the center of the search-circle.If True, the nearest neighbours are searched relative to the closest identified data point.
If False, the nearest neighbours are searched relative to the click position.
consecutive_pick
: Pick data points individually or altogether.If True, callbacks are executed for each picked point individually
If False, callbacks are executed only once and get lists of all picked values as input-arguments.
Set the picker-properties (number of picked points, max. |
from eomaps import Maps
import numpy as np
# create some random data
x, y = np.mgrid[-30:67, -12:50]
data = np.random.randint(0, 100, x.shape)
# a callback to indicate the search-radius
def indicate_search_radius(m, pos, *args, **kwargs):
art = m.add_marker(
xy=(np.atleast_1d(pos[0])[0],
np.atleast_1d(pos[1])[0]),
shape="ellipses", radius=m.tree.d, radius_crs="out",
n=100, fc="none", ec="k", lw=2)
m.cb.pick.add_temporary_artist(art)
# a callback to set the number of picked neighbours
def pick_n_neighbours(m, n, **kwargs):
m.cb.pick.set_props(n=n)
m = Maps()
m.add_feature.preset.coastline()
m.set_data(data, x, y)
m.plot_map()
m.cb.pick.set_props(n=50, search_radius=10, pick_relative_to_closest=True)
m.cb.pick.attach.annotate()
m.cb.pick.attach.mark(fc="none", ec="r")
m.cb.pick.attach(indicate_search_radius, m=m)
for key, n in (("1", 1), ("2", 9), ("3", 50), ("4", 500)):
m.cb.keypress.attach(pick_n_neighbours, key=key, m=m, n=n)
|
![]() |
Picking a dataset without plotting it firstο
It is possible to attach pick
callbacks to a Maps
object without plotting the data first
by using Maps.make_dataset_pickable()
.
from eomaps import Maps
m = Maps()
m.set_extent((0, 40, 30, 70))
m.add_feature.preset.coastline()
m.set_data([1, 2, 3], [10, 20, 30], [40, 50, 60])
m.make_dataset_pickable()
# now it's possible to attach pick-callbacks even though the data is still "invisible"
m.cb.pick.attach.annotate()
Note
Using make_dataset_pickable()
is ONLY necessary if you want to use pick
callbacks without actually plotting the data! Otherwise a call to Maps.plot_map()
is sufficient!
Make the associated dataset pickable without plotting it first. |