Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 1 addition & 72 deletions docs/insets_panels.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@
)

# %%
import numpy as np
import ultraplot as uplt
import numpy as np

state = np.random.RandomState(51423)
data = (state.rand(20, 20) - 0.48).cumsum(axis=1).cumsum(axis=0)
Expand Down Expand Up @@ -192,74 +192,3 @@
)
ix.format(xlim=(2, 4), ylim=(2, 4), color="red8", linewidth=1.5, ticklabelweight="bold")
ix.pcolormesh(data, cmap="Grays", levels=N, inbounds=False)

# %% [raw] raw_mimetype="text/restructuredtext"
# Hawkeye map insets
# ~~~~~~~~~~~~~~~~~~
#
# :class:`~ultraplot.axes.GeoAxes` adds :meth:`~ultraplot.axes.GeoAxes.hawkeye`
# for geographic callout maps. The inset is anchored at ``xy`` in a parent coordinate
# system, and its ``size`` is a fraction of the parent axes. Supply ``extent`` to set
# the inset map scope and draw a matching indicator and optional connectors on the
# parent map. Hawkeyes are excluded from automatic layout, so they can extend beyond
# the parent axes without reserving subplot space.
#
# Rectangular hawkeyes preserve both the requested extent and projection scale. A
# circular frame cannot simultaneously preserve projection scale and display an exact
# non-square extent. Circular hawkeyes therefore expand the shorter projected dimension
# to retain the projection; use a square extent when the exact circular map scope is
# important, or pass ``aspect='auto'`` to fit the exact extent with distortion.
#
# The following dependency-free example shows a Singapore city locator on a world map.
# The returned inset is an ordinary geographic axes, so optional geospatial libraries
# can draw external data inside it. For example, `OSMnx <https://osmnx.readthedocs.io/>`__
# can provide street geometry when it is installed separately:
#
# .. code-block:: python
#
# import osmnx as ox
# from cartopy import crs as ccrs
#
# network = ox.graph_from_point((1.3521, 103.8198), dist=8_000, network_type="drive")
# streets = ox.graph_to_gdfs(network, nodes=False)
# streets.plot(ax=inax, color="0.3", linewidth=0.4, transform=ccrs.PlateCarree())
#
# The data download and OpenStreetMap attribution are the responsibility of the
# application using that optional integration.

# %%
singapore = (103.8198, 1.3521)
fig, ax = uplt.subplots(proj="robin", refwidth=4)
ax.format(land=True, landcolor="gray8", oceancolor="blue9")
ax.plot(
*singapore,
marker="o",
color="red",
markeredgecolor="white",
markeredgewidth=0.8,
ms=5,
transform="cyl",
)
ax.text(106, 4, "Singapore", color="red", size=7, transform="map")
inax = ax.hawkeye(
(0.97, 0.97),
size=0.23,
anchor="ur",
proj="merc",
extent=(103.76, 103.90, 1.27, 1.41),
shape="circle",
target="circle",
connectors="line",
color="red",
indicator_kw={"linewidth": 1.5},
)
inax.format(land=True, landcolor="gray9", oceancolor="blue9")
inax.plot(
*singapore,
marker="o",
color="red",
markeredgecolor="white",
markeredgewidth=0.8,
ms=5,
transform="cyl",
)
19 changes: 1 addition & 18 deletions ultraplot/axes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -750,20 +750,6 @@ def __call__(self, ax, renderer): # noqa: U100
return bbox


class _AspectAwareTransformedBoundsLocator(_TransformedBoundsLocator):
"""Preserve an inset's lower-left anchor after box-aspect adjustment."""

def __call__(self, ax, renderer):
bbox = super().__call__(ax, renderer)
aspect = ax.get_aspect()
if aspect == "auto" or ax.get_adjustable() != "box":
return bbox
box_aspect = float(aspect) * ax.get_data_ratio()
fig_bbox = ax.figure.bbox
fig_aspect = fig_bbox.height / fig_bbox.width
return bbox.shrunk_to_aspect(box_aspect, bbox, fig_aspect)


class _SideColorbarLocator:
"""Position a side colorbar beyond its parent axes decorations."""

Expand Down Expand Up @@ -1072,9 +1058,8 @@ def _add_inset_axes(
Add an inset axes using arbitrary projection.
"""
# Converting transform to figure-relative coordinates
bounds_input = bounds
transform = self._get_transform(transform, "axes")
locator = self._make_inset_locator(bounds_input, transform)
locator = self._make_inset_locator(bounds, transform)
bounds = locator(self, None).bounds
label = kwargs.pop("label", "inset_axes")
zorder = _not_none(zorder, 4)
Expand All @@ -1092,8 +1077,6 @@ def _add_inset_axes(
# automatically if we used data coords. Called by ax.apply_aspect()
cls = mproj.get_projection_class(kwargs.pop("projection"))
ax = cls(self.figure, bounds, zorder=zorder, label=label, **kwargs)
if ax._name in ("cartopy", "basemap"):
locator = _AspectAwareTransformedBoundsLocator(bounds_input, transform)
ax.set_axes_locator(locator)
ax._inset_parent = self
ax._inset_bounds = bounds
Expand Down
Loading