Skip to content

Commit

Permalink
Merge pull request #150 from raphaelquast/dev
Browse files Browse the repository at this point in the history
Merge for EOmaps v6.1.2
  • Loading branch information
raphaelquast authored Mar 5, 2023
2 parents 490a2dd + 09b65ca commit 3b73bb8
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 40 deletions.
6 changes: 3 additions & 3 deletions eomaps/_shapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ def __call__(self, radius=None, n=None):

@property
def _initargs(self):
return dict(radius=self._radius, n=self.n)
return dict(radius=self._radius, n=self._n)

@property
def n(self):
Expand Down Expand Up @@ -572,7 +572,7 @@ def __call__(self, radius="estimate", radius_crs="in", n=None):

@property
def _initargs(self):
return dict(radius=self._radius, radius_crs=self.radius_crs, n=self.n)
return dict(radius=self._radius, radius_crs=self.radius_crs, n=self._n)

@property
def n(self):
Expand Down Expand Up @@ -835,7 +835,7 @@ def _initargs(self):
return dict(
radius=self._radius,
radius_crs=self.radius_crs,
n=self.n,
n=self._n,
mesh=self.mesh,
)

Expand Down
2 changes: 1 addition & 1 deletion eomaps/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "6.1.1"
__version__ = "6.1.2"
101 changes: 76 additions & 25 deletions eomaps/eomaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,7 @@ def new_inset_map(
inset_crs=4326,
layer=None,
boundary=True,
background_color="w",
shape="ellipses",
indicate_extent=True,
):
Expand Down Expand Up @@ -889,6 +890,14 @@ def new_inset_map(
"lw" (e.g. linewidth)
The default is True.
background_color: str, tuple or None
The background color to use.
- if str: a matplotlib color identifier (e.g. "r", "#162347")
- if tuple: a RGB or RGBA tuple (values must be in the range 0-1)
- If None, no background patch will be drawn (e.g. transparent)
The default is "w" (e.g. white)
shape : str, optional
The shape to use. Can be either "ellipses", "rectangles" or "geod_circles".
The default is "ellipses".
Expand Down Expand Up @@ -977,6 +986,7 @@ def new_inset_map(
xy_crs=xy_crs,
radius_crs=radius_crs,
boundary=boundary,
background_color=background_color,
shape=shape,
indicate_extent=indicate_extent,
)
Expand Down Expand Up @@ -2339,7 +2349,12 @@ def set_extent(self, extent, crs=None):
# resetted when plotting data!

# ( e.g. once .set_extent is called .plot_map does NOT set the extent!)
self.ax.set_extent(extent)
if crs is not None:
crs = self._get_cartopy_crs(crs)
else:
crs = Maps.CRS.PlateCarree()

self.ax.set_extent(extent, crs=crs)
self._set_extent_on_plot = False

def plot_map(
Expand Down Expand Up @@ -3220,6 +3235,21 @@ def _init_figure(self, ax=None, plot_crs=None, **kwargs):
# variable of the parent Maps-object while keeping the figure open
# causes all weakrefs to be garbage-collected!
self.parent.f._EOmaps_parent = self.parent._real_self

if self.parent._cid_companion_key is None:
# attach a callback to show/hide the window with the "w" key

# NOTE the companion-widget is ONLY attahed to the parent map
# since it will identify the clicked map automatically! The
# widget will only be initialized on Maps-objects that create
# NEW axes. This is required to make sure that any additional
# Maps-object on the same axes will then always use the
# same widget. (otherwise each layer would get its own widget)

self.parent._cid_companion_key = self.f.canvas.mpl_connect(
"key_press_event", self.parent._open_companion_widget_cb
)

newfig = True
else:
newfig = False
Expand Down Expand Up @@ -3279,6 +3309,7 @@ def _init_figure(self, ax=None, plot_crs=None, **kwargs):
self.cb._init_cbs()

if newax: # only if a new axis has been created
self._new_axis_map = True

# explicitly set initial limits to global to avoid issues if NE-features
# are added (and clipped) before actual limits are set
Expand All @@ -3292,17 +3323,8 @@ def _init_figure(self, ax=None, plot_crs=None, **kwargs):
self._cid_xlim = self.ax.callbacks.connect(
"ylim_changed", self._on_ylims_change
)

if self._cid_companion_key is None:
# attach a callback to show/hide the window with the "w" key

# NOTE the companion-widget is ONLY initialized on Maps-objects that
# create NEW axes. This is required to make sure that any additional
# Maps-object on the same axes will then always use the same widget.
# (otherwise each layer would get its own widget)
self._cid_companion_key = self.f.canvas.mpl_connect(
"key_press_event", self._open_companion_widget_cb
)
else:
self._new_axis_map = False

if self.parent == self: # use == instead of "is" since the parent is a proxy!
# only attach resize- and close-callbacks if we initialize a parent
Expand Down Expand Up @@ -4484,39 +4506,52 @@ def _open_companion_widget_cb(self, event):
if event.key != self._companion_widget_key:
return

if event.inaxes != self.ax:
clicked_map = None
for m in (self.parent, *self.parent._children):
if not m._new_axis_map:
# only search for Maps-object that initialized new axes
continue

if m.ax.contains_point((event.x, event.y)):
clicked_map = m

if clicked_map is None:
print(
"EOmaps: To activate the 'Companion Widget' you must "
"position the mouse on top of an EOmaps Map!"
)
return

# hide all other companion-widgets
for m in (self.parent, *self.parent._children):
if m == self:
if m == clicked_map:
continue
if m._companion_widget is not None and m._companion_widget.isVisible():
m._companion_widget.hide()
m._indicate_companion_map(False)

if self._companion_widget is None:
self._init_companion_widget()
if clicked_map._companion_widget is None:
clicked_map._init_companion_widget()

if self._companion_widget is not None:
if self._companion_widget.isVisible():
self._companion_widget.hide()
self._indicate_companion_map(False)
if clicked_map._companion_widget is not None:
if clicked_map._companion_widget.isVisible():
clicked_map._companion_widget.hide()
clicked_map._indicate_companion_map(False)
else:
self._companion_widget.show()
self._indicate_companion_map(True)
clicked_map._companion_widget.show()
clicked_map._indicate_companion_map(True)

# execute all actions that should trigger before opening the widget
# (e.g. update tabs to show visible layers etc.)
for f in self._on_show_companion_widget:
for f in clicked_map._on_show_companion_widget:
f()

# Do NOT activate the companion widget in here!!
# Activating the window during the callback steals focus and
# as a consequence the key-released-event is never triggered
# on the figure and "w" would remain activated permanently.
self.f.canvas.key_release_event("w")
self._companion_widget.activateWindow()
clicked_map.f.canvas.key_release_event("w")
clicked_map._companion_widget.activateWindow()

def _init_companion_widget(self, show_hide_key="w"):
"""
Expand Down Expand Up @@ -4671,6 +4706,7 @@ def __init__(
shape="ellipses",
indicate_extent=True,
boundary=True,
background_color="w",
**kwargs,
):

Expand Down Expand Up @@ -4758,6 +4794,21 @@ def __init__(
parent, layer=parent.layer, permanent=True, **extent_kwargs
)

# add a background patch to the "all" layer
if background_color is not None:
self._add_background_patch(color=background_color, layer="all")

def _add_background_patch(self, color, layer="all"):
(art,) = self.ax.fill(
[0, 0, 1, 1],
[0, 1, 1, 0],
fc=color,
ec="none",
zorder=-np.inf,
transform=self.ax.transAxes,
)
self.BM.add_bg_artist(art, layer=layer)

def _handle_spines(self):
spine = self.ax.spines["geo"]
if spine not in self.BM._bg_artists.get("__inset___SPINES__", []):
Expand Down
5 changes: 4 additions & 1 deletion eomaps/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ def d(self):

@property
def layer(self):
return self._layer
if self._layer is None:
return self.m.layer
else:
return self._layer

@property
def auto_n(self):
Expand Down
42 changes: 34 additions & 8 deletions eomaps/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1366,16 +1366,24 @@ def __init__(self, m):

self._clear_on_layer_change = False

def _get_all_map_axes(self):
maxes = {
m.ax for m in (self._m.parent, *self._m.parent._children) if m._new_axis_map
}
return maxes

def _get_managed_axes(self):
return (*self._get_all_map_axes(), *self._managed_axes)

def _get_unmanaged_axes(self):
# return a list of all axes that are not managed by the blit-manager
# (to ensure that "unmanaged" axes are drawn as well)

# EOmaps axes
maxes = {m.ax for m in (self._m.parent, *self._m.parent._children)}
managed_axes = self._get_managed_axes()
allaxes = set(self._m.f.axes)

unmanaged_axes = allaxes.difference(maxes, self._managed_axes)

unmanaged_axes = allaxes.difference(managed_axes)
return unmanaged_axes

@property
Expand Down Expand Up @@ -1462,7 +1470,7 @@ def _get_active_bg(self, exclude_artists=None):
# (done by putting the patch on the __BG__ layer!)

# get rid of the axes background patch
for ax_i in self._m.f.axes:
for ax_i in self._get_all_map_axes():
stack.enter_context(
ax_i.patch._cm_set(facecolor="none", edgecolor="none")
)
Expand Down Expand Up @@ -1683,7 +1691,7 @@ def _do_fetch_bg(self, layer, bbox=None):
with ExitStack() as stack:
# get rid of the axes background patches
# (the figure background patch is on the "__BG__" layer)
for ax_i in self._m.f.axes:
for ax_i in self._get_all_map_axes():
stack.enter_context(
ax_i.patch._cm_set(facecolor="none", edgecolor="none")
)
Expand All @@ -1701,7 +1709,10 @@ def _do_fetch_bg(self, layer, bbox=None):
# avoid fetching artists from the "all" layer for private layers
allartists = self.get_bg_artists(layer)
else:
allartists = self.get_bg_artists(["all", layer])
if layer.startswith("__inset"):
allartists = self.get_bg_artists(["__inset_all", layer])
else:
allartists = self.get_bg_artists(["all", layer])

# check if all artists are not stale
no_stale_artists = all(not art.stale for art in allartists)
Expand All @@ -1721,9 +1732,15 @@ def _do_fetch_bg(self, layer, bbox=None):

@contextmanager
def _make_layer_artists_visible(self, layer):
layers = [layer]
if layer.startswith("__inset_"):
layers.append("__inset_all")
else:
layers.append("all")

try:
for l, artists in self._bg_artists.items():
if l not in [layer, "all"]:
if l not in layers:
# artists on "all" are always visible!
# make all artists of other layers invisible
for a in artists:
Expand Down Expand Up @@ -1923,6 +1940,15 @@ def add_bg_artist(self, art, layer=None):
f()

def remove_bg_artist(self, art, layer=None):
# handle the "__inset_" prefix of inset-map artists
if (
layer is not None
and getattr(art, "axes", None) is not None
and art.axes.get_label() == "inset_map"
and not layer.startswith("__inset_")
):
layer = "__inset_" + str(layer)

removed = False
if layer is None:
layers = []
Expand Down Expand Up @@ -2183,7 +2209,7 @@ class bbox:

# let the GUI event loop process anything it has to do
# don't do this! it is causing infinite loops
cv.flush_events()
# cv.flush_events()

def blit_artists(self, artists, bg="active", blit=True):
"""
Expand Down
3 changes: 1 addition & 2 deletions eomaps/qtcompanion/widgets/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1266,9 +1266,8 @@ def __init__(self, m=None, show_editor=False):
self.artist_tabs = ArtistEditorTabs(m=self.m)

self.newlayer = NewLayerWidget(m=self.m)
# self.newlayer.new_layer_name.returnPressed.connect(self.artist_tabs.tabBar().populate)
# # re-populate layers on new layer creation
# self.newlayer.NewLayerCreated.connect(self.artist_tabs.tabBar().populate)
self.newlayer.NewLayerCreated.connect(self.artist_tabs.populate)
# set active tab to the new tab on layer creation
# self.newlayer.NewLayerCreated[str].connect(self.artist_tabs.set_current_tab_by_name)

Expand Down

0 comments on commit 3b73bb8

Please sign in to comment.