diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index c55f77811859..f91b3141c244 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -440,7 +440,7 @@ def indicate_inset(self, bounds=None, inset_ax=None, *, transform=None, transform : `.Transform` Transform for the rectangle coordinates. Defaults to - ``ax.transAxes``, i.e. the units of *rect* are in Axes-relative + ``ax.transData``, i.e. the units of *rect* are in the Axes' data coordinates. facecolor : :mpltype:`color`, default: 'none' diff --git a/lib/matplotlib/inset.py b/lib/matplotlib/inset.py index bab69491303e..52e1f635b35d 100644 --- a/lib/matplotlib/inset.py +++ b/lib/matplotlib/inset.py @@ -79,6 +79,13 @@ def _shared_setter(self, prop, val): artist.setp([self._rectangle, *self._connectors], prop, val) + @artist.Artist.axes.setter + def axes(self, new_axes): + # Set axes on the rectangle (required for some external transforms to work) as + # well as the InsetIndicator artist. + self.rectangle.axes = new_axes + artist.Artist.axes.fset(self, new_axes) + def set_alpha(self, alpha): # docstring inherited self._shared_setter('alpha', alpha) @@ -171,7 +178,7 @@ def _update_connectors(self): # parent artist. p = ConnectionPatch( xyA=xy_inset_ax, coordsA=self._inset_ax.transAxes, - xyB=xy_data, coordsB=self.axes.transData, + xyB=xy_data, coordsB=self.rectangle.get_data_transform(), arrowstyle="-", edgecolor=self._edgecolor, alpha=self.get_alpha(), linestyle=self._linestyle, linewidth=self._linewidth) @@ -182,7 +189,7 @@ def _update_connectors(self): existing.xy1 = xy_inset_ax existing.xy2 = xy_data existing.coords1 = self._inset_ax.transAxes - existing.coords2 = self.axes.transData + existing.coords2 = self.rectangle.get_data_transform() if existing is None: # decide which two of the lines to keep visible.... diff --git a/lib/matplotlib/tests/baseline_images/test_inset/zoom_inset_transform.png b/lib/matplotlib/tests/baseline_images/test_inset/zoom_inset_transform.png new file mode 100644 index 000000000000..4990efa5cfc9 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_inset/zoom_inset_transform.png differ diff --git a/lib/matplotlib/tests/test_inset.py b/lib/matplotlib/tests/test_inset.py index c25580214c80..906231f799e6 100644 --- a/lib/matplotlib/tests/test_inset.py +++ b/lib/matplotlib/tests/test_inset.py @@ -4,6 +4,7 @@ import matplotlib.colors as mcolors import matplotlib.pyplot as plt +import matplotlib.transforms as mtransforms from matplotlib.testing.decorators import image_comparison, check_figures_equal @@ -104,3 +105,38 @@ def test_zoom_inset_connector_styles(): # Make one visible connector a different style indicator.connectors[1].set_linestyle('dashed') indicator.connectors[1].set_color('blue') + + +@image_comparison(['zoom_inset_transform.png'], remove_text=True, style='mpl20', + tol=0.01) +def test_zoom_inset_transform(): + fig, ax = plt.subplots() + + ax_ins = ax.inset_axes([0.2, 0.2, 0.3, 0.15]) + ax_ins.set_ylim([0.3, 0.6]) + ax_ins.set_xlim([0.5, 0.9]) + + tr = mtransforms.Affine2D().rotate_deg(30) + indicator = ax.indicate_inset_zoom(ax_ins, transform=tr + ax.transData) + for conn in indicator.connectors: + conn.set_visible(True) + + +def test_zoom_inset_external_transform(): + # Smoke test that an external transform that requires an axes (i.e. + # Cartopy) will work. + class FussyDataTr: + def _as_mpl_transform(self, axes=None): + if axes is None: + raise ValueError("I am a fussy transform that requires an axes") + return axes.transData + + fig, ax = plt.subplots() + + ax_ins = ax.inset_axes([0.2, 0.2, 0.3, 0.15]) + ax_ins.set_xlim([0.7, 0.8]) + ax_ins.set_ylim([0.7, 0.8]) + + ax.indicate_inset_zoom(ax_ins, transform=FussyDataTr()) + + fig.draw_without_rendering()