raphaelquast / EOmaps

A library to create interactive maps of geographical datasets
https://eomaps.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
339 stars 25 forks source link

inset maps do not render/plot stuff things outside the top api #242

Closed ocehugo closed 6 months ago

ocehugo commented 6 months ago

Describe the bug

When using the Maps.new_insetmap instance, anything manually added to the axis via the m.ax object is not rendered inside the inset. The only possible things to be rendered within the inset are from the top API (layers,`.add*methods, or.set_data`).

This doesn't happen when using a standard Maps class, where one can access the m.ax property and plot anything, as long as it is in the right crs, and call plt.draw() to update the map.

A typical example is plotting several data layers, such as a contour and a raster. The raster can be rendered via set_data in both maps, but the contour can only be rendered in the main map, leaving the inset without the artist. This also happens with lines and polygons, although one could convert to geopandas and use add_gdf.

The documentation says that "inset maps" have features disabled, but it is not explicit about what is disabled. If this is "a feature," I would like to learn how to turn it off to render things not implemented in the top object API.

To Reproduce

from eomaps import Maps
m = Maps(ax=131)
m.add_feature.preset.coastline()
m.set_data(data, x, y)
m.set_shape.raster()
m.set_classify.Quantiles(k=10)
m.plot_map(cmap="tab10", vmin=-10, vmax=40)

m_i = m.new_inset_map(xy=(-5, 35), radius=8, 
                      plot_position=(0.7, .5), plot_size=.7, indicator_line=True)
m_i.add_title("A zoomed-in view on a dataset!", y=1.05)

m_i.add_feature.preset.coastline()
m_i.add_feature.preset.ocean(alpha=0.4, zorder=10, hatch="///", ec="darkblue")

m_i.inherit_data(m)            # inherit the data from "m"
m_i.inherit_classification(m)  # inherit the classification from "m"
m_i.set_shape.rectangles()     # switch to a different shape for plotting
m_i.plot_map(ec="k", lw=0.5)

m.ax.plot(-10,34,'rs',zorder=100) # X this is drawn
m_i.ax.plot(-10,34,'rs',zorder=100) # Y but not here.
m.show()
plt.draw() # need this to render X step.

Expected behavior a red square is rendered within the inset.

General information: linux eomaps-8.2 python-3.11.7

raphaelquast commented 6 months ago

Thank you very much for taking the time to report this issue. I can confirm that this is indeed a bug (and not a feature)... it will be fixed in the next version!

The good thing is that the issue is connected to the way how "unmanaged" matplotlib artists are handled, so you can circumvent it by explicitly telling EOmaps how to treat the artists: (this way plt.draw() should no longer be necessary and you can also control the layer at which the artists are visible)

(marker1, ) = m.ax.plot(-10,34,'rs',zorder=100) # X this is drawn
(marker2, ) = m_i.ax.plot(-10,34,'rs',zorder=100) # Y but not here.

# explicitly add artists as "background artists" to the blit-manager
# (the blit-manager is shared across all Maps objects that belong to the same figure 
# so it does not matter if we use  'm' or 'm_i' to access it)
m.BM.add_bg_artist(marker1, layer=m.layer)
m.BM.add_bg_artist(marker2, layer=m.layer)

For more details, have a look at the short paragraph on "Artists added with methods outside of EOmaps" here: https://eomaps.readthedocs.io/en/latest/api_basics.html#layer-management

raphaelquast commented 6 months ago

As another alternative, you can of course also use m.add_marker to add the indicators directly: (see https://eomaps.readthedocs.io/en/latest/api_annotations_markers_etc.html#markers)

m.add_marker(xy=(-10, 34), fc="r", shape="scatter_points", marker="s", radius=20)
m_i.add_marker(xy=(-10, 34), fc="r", shape="scatter_points", marker="s", radius=20)
ocehugo commented 6 months ago

Hi, thank you for the super fast reply.

For more details, have a look at the short paragraph on "Artists added with methods outside of EOmaps" >here: https://eomaps.readthedocs.io/en/latest/api_basics.html#layer-management

Ow, I missed that section on the docs! Cheers

raphaelquast commented 6 months ago

Hey, @ocehugo, if you update to the latest version v8.2.1 this should be fixed!