From 57d2c209e3864e2d7b6e8b8f82cae98b73cd4d6d Mon Sep 17 00:00:00 2001 From: Raphael Quast Date: Fri, 8 Dec 2023 21:37:51 +0100 Subject: [PATCH 01/13] fix spines are not properly re-drawn with m.set_frame if rounded=0 --- eomaps/eomaps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eomaps/eomaps.py b/eomaps/eomaps.py index 6d43f01ab..547227f15 100644 --- a/eomaps/eomaps.py +++ b/eomaps/eomaps.py @@ -5705,5 +5705,5 @@ def cb(*args, **kwargs): self.BM._before_fetch_bg_actions.append(cb) self.ax._EOmaps_rounded_spine_attached = True - self.redraw("__SPINES__") + self.redraw("__SPINES__") self.redraw("__BG__") From 7e8315ccbcf4d4cb741a1c2f86660531fe491546 Mon Sep 17 00:00:00 2001 From: Raphael Quast Date: Sat, 9 Dec 2023 00:03:07 +0100 Subject: [PATCH 02/13] avoid activating snapshot_on_update by default --- eomaps/eomaps.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/eomaps/eomaps.py b/eomaps/eomaps.py index 547227f15..e70918ee5 100644 --- a/eomaps/eomaps.py +++ b/eomaps/eomaps.py @@ -105,20 +105,7 @@ def _handle_backends(): "To change, use Maps.config(use_interactive_mode=True/False)." ) - # check if we are in an ipython console using the inline-backend. - # If yes, put a snapshot of the map into the active cell on each update - if BlitManager._snapshot_on_update is None: - try: - __IPYTHON__ - except NameError: - BlitManager._snapshot_on_update = False - else: - active_backend = plt.get_backend() - # print a snapshot to the active ipython cell in case the - # inline-backend is used - if active_backend in ["module://matplotlib_inline.backend_inline"]: - BlitManager._snapshot_on_update = True - + BlitManager._snapshot_on_update = False # hardcoded list of available mapclassify-classifiers # (to avoid importing it on startup) From e6f4c8e711783daadd64244742f7ccb58f492e46 Mon Sep 17 00:00:00 2001 From: Raphael Quast Date: Sat, 9 Dec 2023 00:42:12 +0100 Subject: [PATCH 03/13] fix creating a snapshot on m.show() in jupyter inline backend --- eomaps/eomaps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eomaps/eomaps.py b/eomaps/eomaps.py index e70918ee5..ceeed5735 100644 --- a/eomaps/eomaps.py +++ b/eomaps/eomaps.py @@ -3373,7 +3373,7 @@ def show(self, clear=True): # print a snapshot to the active ipython cell in case the # inline-backend is used if active_backend in ["module://matplotlib_inline.backend_inline"]: - self.BM.update(clear_snapshot=clear) + self.snapshot(clear=clear) else: plt.show() From 47eacffaa09f7b67e5dd5d84ba9e49a287b222d9 Mon Sep 17 00:00:00 2001 From: Raphael Quast Date: Sat, 9 Dec 2023 00:48:20 +0100 Subject: [PATCH 04/13] make pre-commit happy --- eomaps/eomaps.py | 1 + 1 file changed, 1 insertion(+) diff --git a/eomaps/eomaps.py b/eomaps/eomaps.py index ceeed5735..c45e01851 100644 --- a/eomaps/eomaps.py +++ b/eomaps/eomaps.py @@ -107,6 +107,7 @@ def _handle_backends(): BlitManager._snapshot_on_update = False + # hardcoded list of available mapclassify-classifiers # (to avoid importing it on startup) _CLASSIFIERS = ( From 228ae9caacdc67a2e8847e0ef309e6d3845a66e4 Mon Sep 17 00:00:00 2001 From: Raphael Quast Date: Sat, 9 Dec 2023 01:03:01 +0100 Subject: [PATCH 05/13] fix setting snapshot_on_update --- eomaps/eomaps.py | 2 -- eomaps/helpers.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/eomaps/eomaps.py b/eomaps/eomaps.py index c45e01851..f6da85fc7 100644 --- a/eomaps/eomaps.py +++ b/eomaps/eomaps.py @@ -105,8 +105,6 @@ def _handle_backends(): "To change, use Maps.config(use_interactive_mode=True/False)." ) - BlitManager._snapshot_on_update = False - # hardcoded list of available mapclassify-classifiers # (to avoid importing it on startup) diff --git a/eomaps/helpers.py b/eomaps/helpers.py index 3d7dd4076..e2c5d4a06 100644 --- a/eomaps/helpers.py +++ b/eomaps/helpers.py @@ -1539,7 +1539,7 @@ def apply_layout(self, layout): class BlitManager: """Manager used to schedule draw events, cache backgrounds, etc.""" - _snapshot_on_update = None + _snapshot_on_update = False def __init__(self, m): """ From 96312d7f3dd1965e1788901430d2f64dd2f2c2f6 Mon Sep 17 00:00:00 2001 From: Raphael Quast Date: Mon, 11 Dec 2023 10:16:55 +0100 Subject: [PATCH 06/13] make sure the colorbar always uses the associated figure --- eomaps/colorbar.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eomaps/colorbar.py b/eomaps/colorbar.py index 8ca68dc83..034f79f1d 100644 --- a/eomaps/colorbar.py +++ b/eomaps/colorbar.py @@ -916,7 +916,9 @@ def _plot_colorbar(self): horizontal = self._orientation == "horizontal" n_cmap = plt.cm.ScalarMappable(cmap=self._cmap, norm=self._norm) - self.cb = plt.colorbar( + # avoid using "plt.colorbar" since it might not properly recognize + # the associated figure (e.g. plt.gcf() might point somewhere else)! + self.cb = self._m.f.colorbar( n_cmap, cax=self.ax_cb, extend=self._extend, From 4c7b6313cf8609f196782b44805719fbf8cdd1a6 Mon Sep 17 00:00:00 2001 From: Raphael Quast Date: Mon, 11 Dec 2023 10:17:16 +0100 Subject: [PATCH 07/13] add `.show` and `.snapshot` to `MapsGrid` objects --- eomaps/mapsgrid.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/eomaps/mapsgrid.py b/eomaps/mapsgrid.py index 2174beb7b..d208b0797 100644 --- a/eomaps/mapsgrid.py +++ b/eomaps/mapsgrid.py @@ -527,3 +527,11 @@ def apply_layout(self, *args, **kwargs): @wraps(Maps.edit_layout) def edit_layout(self, *args, **kwargs): return self.parent.edit_layout(*args, **kwargs) + + @wraps(Maps.show) + def show(self, *args, **kwargs): + return self.parent.show(*args, **kwargs) + + @wraps(Maps.snapshot) + def snapshot(self, *args, **kwargs): + return self.parent.snapshot(*args, **kwargs) From 1215d4f0f71718d47dedb4a86a4fd540544a83fd Mon Sep 17 00:00:00 2001 From: Raphael Quast Date: Mon, 11 Dec 2023 16:25:52 +0100 Subject: [PATCH 08/13] make sure m.show_layer adds a snapshot with jupyter-inline --- eomaps/eomaps.py | 11 +++++++++++ eomaps/helpers.py | 6 +----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/eomaps/eomaps.py b/eomaps/eomaps.py index f6da85fc7..cd18ccb56 100644 --- a/eomaps/eomaps.py +++ b/eomaps/eomaps.py @@ -3342,6 +3342,12 @@ def show_layer(self, *args, clear=True): self.BM.bg_layer = name self.BM.update() + # plot a snapshot to jupyter notebook cell if inline backend is used + if not self.BM._snapshot_on_update and plt.get_backend() in [ + "module://matplotlib_inline.backend_inline" + ]: + self.snapshot(clear=clear) + def show(self, clear=True): """ Show the map (only required for non-interactive matplotlib backends). @@ -3411,6 +3417,11 @@ def snapshot(self, *layer, transparent=False, clear=False): >>> m.snapshot("base", ("ocean", .5), transparent=True) """ + if getattr(self, "_snapshotting", False): + # this is necessary to avoid recursions with show_layer + # in jupyter-notebook inline backend + return + try: self._snapshotting = True diff --git a/eomaps/helpers.py b/eomaps/helpers.py index e2c5d4a06..c46a6b60c 100644 --- a/eomaps/helpers.py +++ b/eomaps/helpers.py @@ -2727,11 +2727,7 @@ class bbox: # don't do this! it is causing infinite loops # cv.flush_events() - if ( - blit - and not getattr(self._m, "_snapshotting", False) - and BlitManager._snapshot_on_update is True - ): + if blit and BlitManager._snapshot_on_update is True: self._m.snapshot(clear=clear_snapshot) def blit_artists(self, artists, bg="active", blit=True): From 39113b7b5444b79647671186e8df832db1c788ac Mon Sep 17 00:00:00 2001 From: Raphael Quast Date: Mon, 11 Dec 2023 20:50:46 +0100 Subject: [PATCH 09/13] make sure layers are re-fetched in case colorbars change axes sizes --- eomaps/colorbar.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eomaps/colorbar.py b/eomaps/colorbar.py index 034f79f1d..b5271a9b7 100644 --- a/eomaps/colorbar.py +++ b/eomaps/colorbar.py @@ -496,6 +496,9 @@ def set_hist_size(self, size=None): _TransformedBoundsLocator(cbpos, self._ax.transAxes) ) + # re-fetch ALL layers (since axes-positions have changed!) + self._m.BM._refetch_layer("all") + if self._hist_size > 0.0001: self.ax_cb_plot.set_visible(True) From f13e5d96bcf8677a6b001511a02d59268b651008 Mon Sep 17 00:00:00 2001 From: Raphael Date: Wed, 13 Dec 2023 10:46:25 +0100 Subject: [PATCH 10/13] fix raster-maxsize argument should be parsed as integer --- eomaps/qtcompanion/widgets/files.py | 1 + 1 file changed, 1 insertion(+) diff --git a/eomaps/qtcompanion/widgets/files.py b/eomaps/qtcompanion/widgets/files.py index fd28a0775..cb14c56ef 100644 --- a/eomaps/qtcompanion/widgets/files.py +++ b/eomaps/qtcompanion/widgets/files.py @@ -181,6 +181,7 @@ class ShapeSelector(QtWidgets.QFrame): mask_radius=(float,), flat=(str_to_bool,), aggregator=(str,), + maxsize=(int,), ) def __init__(self, *args, m=None, default_shape="shade_raster", **kwargs): From 7a20e49eb2ce22c603120fa7c2632d00480968f1 Mon Sep 17 00:00:00 2001 From: Raphael Date: Wed, 13 Dec 2023 22:15:55 +0100 Subject: [PATCH 11/13] fix treatment of cb-histogram weights with `out_of_range_vals="masked"` --- eomaps/colorbar.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/eomaps/colorbar.py b/eomaps/colorbar.py index b5271a9b7..17af04bd4 100644 --- a/eomaps/colorbar.py +++ b/eomaps/colorbar.py @@ -892,7 +892,14 @@ def check_data_updated(*args, **kwargs): self._set_extend(z_data) if self._out_of_range_vals == "mask": - z_data = z_data[(z_data >= self._vmin) & (z_data <= self._vmax)] + data_range_mask = (z_data >= self._vmin) & (z_data <= self._vmax) + z_data = z_data[data_range_mask] + + # make sure that histogram weights are masked accordingly if provided + if "weights" in self._hist_kwargs: + self._hist_kwargs["weights"] = self._hist_kwargs["weights"][ + data_range_mask + ] # make sure the norm clips with respect to vmin/vmax # (only clip if either vmin or vmax is not None) From 1bd02f33e713ab0d2ab5d67bc1dec99bd4fb5de9 Mon Sep 17 00:00:00 2001 From: Raphael Date: Tue, 19 Dec 2023 11:03:32 +0100 Subject: [PATCH 12/13] fix restoring visible layer after calling savefig with `transparent=False` (this addresses problems with inset-maps reported in #214) --- eomaps/eomaps.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/eomaps/eomaps.py b/eomaps/eomaps.py index cd18ccb56..d7b9d86cb 100644 --- a/eomaps/eomaps.py +++ b/eomaps/eomaps.py @@ -3513,6 +3513,9 @@ def text(self, *args, layer=None, **kwargs): @wraps(plt.savefig) def savefig(self, *args, refetch_wms=False, rasterize_data=True, **kwargs): """Save the figure.""" + # get the currently visible layer (to restore it after saving is done) + initial_layer = self.BM.bg_layer + if plt.get_backend() == "agg": # make sure that a draw-event was triggered when using the agg backend # (to avoid export-issues with some shapes) @@ -3533,7 +3536,6 @@ def savefig(self, *args, refetch_wms=False, rasterize_data=True, **kwargs): # add the figure background patch as the bottom layer transparent = kwargs.get("transparent", False) if transparent is False: - initial_layer = self.BM.bg_layer showlayer_name = self.BM._get_showlayer_name(initial_layer) layer_with_bg = "|".join(["__BG__", showlayer_name]) self.show_layer(layer_with_bg) @@ -3637,7 +3639,7 @@ def savefig(self, *args, refetch_wms=False, rasterize_data=True, **kwargs): # trigger a redraw of all savelayers to make sure unmanaged artists # and ordinary matplotlib axes are properly drawn self.redraw(*savelayers) - # flush events prior to savefig to avoi dissues with pending draw events + # flush events prior to savefig to avoid issues with pending draw events # that cause wrong positioning of grid-labels and missing artists! self.f.canvas.flush_events() self.f._mpl_orig_savefig(*args, **kwargs) @@ -3645,17 +3647,14 @@ def savefig(self, *args, refetch_wms=False, rasterize_data=True, **kwargs): if redraw is True: # reset the shading-axis-size to the used figure dpi self._update_shade_axis_size() + + # restore the previous layer if background was added on save + if transparent is False: + self.show_layer(initial_layer) + # redraw after the save to ensure that backgrounds are correctly cached self.redraw() - # restore the previous layer - elif transparent is False: - self.BM._refetch_layer("__SPINES__") - self.BM._refetch_layer("__BG__") - self.BM._refetch_layer(layer_with_bg) - self.BM.on_draw(None) - self.show_layer(initial_layer) - def fetch_layers(self, layers=None): """ Fetch (and cache) the layers of a map. From ab2452dbcadc3d1d6a983a0bdbf78dc4f470c780 Mon Sep 17 00:00:00 2001 From: Raphael Date: Wed, 20 Dec 2023 13:11:54 +0100 Subject: [PATCH 13/13] update version to v7.3.3 --- eomaps/_version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eomaps/_version.py b/eomaps/_version.py index 6b5a69c78..40d114c5b 100644 --- a/eomaps/_version.py +++ b/eomaps/_version.py @@ -1 +1 @@ -__version__ = "7.3.2" +__version__ = "7.3.3"