Skip to content

Commit a752929

Browse files
authored
Merge pull request #172 from lukelbd/inset-projs
Support arbitrary projections for inset_axes
2 parents d9e30f7 + f488b65 commit a752929

File tree

1 file changed

+52
-8
lines changed

1 file changed

+52
-8
lines changed

proplot/axes/base.py

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
The base axes class used for all ProPlot figures.
44
"""
55
import numpy as np
6-
from numbers import Integral, Number
6+
import copy
77
import matplotlib.axes as maxes
88
import matplotlib.ticker as mticker
99
import matplotlib.patches as mpatches
1010
import matplotlib.transforms as mtransforms
1111
import matplotlib.collections as mcollections
12+
import matplotlib.projections as mprojections
13+
from numbers import Integral, Number
1214
from .plot import (
1315
_get_transform,
1416
_bar_wrapper, _barh_wrapper, _boxplot_wrapper,
@@ -21,6 +23,7 @@
2123
colorbar_wrapper, legend_wrapper,
2224
)
2325
from .. import gridspec as pgridspec
26+
from .. import constructor
2427
from ..config import rc
2528
from ..utils import units, edges
2629
from ..internals import ic # noqa: F401
@@ -101,6 +104,21 @@
101104
`~matplotlib.axes.Axes.transAxes`,
102105
or `~matplotlib.figure.Figure.transFigure` transforms. Default is
103106
``'axes'``, i.e. `bounds` is in axes-relative coordinates.
107+
proj, projection : str, `cartopy.crs.Projection`, or `~mpl_toolkits.basemap.Basemap`
108+
The map projection specification(s). If not provided, the inset axes
109+
projection is identical to the current axes projection. If ``'cartesian'``,
110+
a `~proplot.axes.CartesianAxes` inset is created. If ``'polar'``, a
111+
`~proplot.axes.PolarAxes` inset is created. Otherwise, the argument is
112+
interpreted by `~proplot.constructor.Proj`, and the result is used
113+
to make a `~proplot.axes.GeoAxes` (in this case the argument can be
114+
a `cartopy.crs.Projection` instance, a `~mpl_toolkits.basemap.Basemap`
115+
instance, or a projection name listed in :ref:`this table <proj_table>`).
116+
proj_kw, projection_kw : dict-like, optional
117+
Keyword arguments passed to `~mpl_toolkits.basemap.Basemap` or
118+
cartopy `~cartopy.crs.Projection` classes on instantiation.
119+
basemap : bool or dict-like, optional
120+
Whether to use `~mpl_toolkits.basemap.Basemap` or
121+
`~cartopy.crs.Projection` for map projections. Default is ``False``.
104122
zorder : float, optional
105123
The `zorder <https://matplotlib.org/3.1.1/gallery/misc/zorder_demo.html>`__
106124
of the axes, should be greater than the zorder of
@@ -1435,8 +1453,9 @@ def inset(self, *args, **kwargs):
14351453

14361454
@docstring.add_snippets
14371455
def inset_axes(
1438-
self, bounds, *, transform=None, zorder=4,
1439-
zoom=True, zoom_kw=None,
1456+
self, bounds, transform=None, zorder=4,
1457+
zoom=None, zoom_kw=None,
1458+
proj=None, proj_kw=None, projection=None, projection_kw=None, basemap=None,
14401459
**kwargs
14411460
):
14421461
"""
@@ -1448,18 +1467,43 @@ def inset_axes(
14481467
else:
14491468
transform = _get_transform(self, transform)
14501469
label = kwargs.pop('label', 'inset_axes')
1470+
proj = _not_none(proj=proj, projection=projection)
1471+
proj_kw = _not_none(proj_kw=proj_kw, projection_kw=projection_kw, default={})
1472+
1473+
# Inherit from current axes
1474+
if proj is None:
1475+
proj = self.name
1476+
if basemap is not None:
1477+
proj_kw['basemap'] = basemap
1478+
if proj_kw:
1479+
warnings._warn_proplot(
1480+
'Inheriting projection from the main axes. '
1481+
f'Ignoring proj_kw keyword args: {proj_kw}'
1482+
)
1483+
if proj in ('cartopy', 'basemap'):
1484+
map_projection = copy.copy(self.projection)
1485+
kwargs.setdefault('map_projection', map_projection)
1486+
1487+
# Create new projection
1488+
elif proj == 'cartesian':
1489+
pass
1490+
elif proj == 'polar':
1491+
proj = 'polar2' # custom proplot name
1492+
else:
1493+
proj_kw.setdefault('basemap', basemap)
1494+
map_projection = constructor.Proj(proj, **proj_kw)
1495+
kwargs.setdefault('map_projection', map_projection)
1496+
proj = 'basemap' if proj_kw['basemap'] else 'cartopy'
14511497

14521498
# This puts the rectangle into figure-relative coordinates.
1453-
from .cartesian import CartesianAxes
14541499
locator = self._make_inset_locator(bounds, transform)
1500+
cls = mprojections.get_projection_class(proj)
14551501
bb = locator(None, None)
1456-
ax = CartesianAxes(
1457-
self.figure, bb.bounds,
1458-
zorder=zorder, label=label, **kwargs
1459-
)
1502+
ax = cls(self.figure, bb.bounds, zorder=zorder, label=label, **kwargs)
14601503

14611504
# The following locator lets the axes move if we used data coordinates,
14621505
# is called by ax.apply_aspect()
1506+
zoom = _not_none(zoom, self.name == ax.name) # only zoom when same projection
14631507
ax.set_axes_locator(locator)
14641508
self.add_child_axes(ax)
14651509
ax._inset_zoom = zoom

0 commit comments

Comments
 (0)