diff --git a/docs/src/whatsnew/dev.rst b/docs/src/whatsnew/dev.rst index 63839825e1..8821c6c676 100644 --- a/docs/src/whatsnew/dev.rst +++ b/docs/src/whatsnew/dev.rst @@ -41,14 +41,18 @@ This document explains the changes made to Iris for this release #. `@rcomer`_ reverted part of the change from :pull:`3906` so that :func:`iris.plot.plot` no longer defaults to placing a "Y" coordinate (e.g. latitude) on the y-axis of the plot. (:issue:`4493`, :pull:`4601`) - -#. `@rcomer`_ enabled passing of scalar objects to :func:`~iris.plot.plot` and + +#. `@rcomer`_ enabled passing of scalar objects to :func:`~iris.plot.plot` and :func:`~iris.plot.scatter`. (:pull:`4616`) #. `@rcomer`_ fixed :meth:`~iris.cube.Cube.aggregated_by` with `mdtol` for 1D cubes where an aggregated section is entirely masked, reported at :issue:`3190`. (:pull:`4246`) +#. `@rcomer`_ ensured that a :class:`matplotlib.axes.Axes`'s position is preserved + when Iris replaces it with a :class:`cartopy.mpl.geoaxes.GeoAxes`, fixing + :issue:`1157`. (:pull:`4273`) + 💣 Incompatible Changes ======================= diff --git a/lib/iris/plot.py b/lib/iris/plot.py index d886ac1cf9..10bd740306 100644 --- a/lib/iris/plot.py +++ b/lib/iris/plot.py @@ -843,7 +843,9 @@ def _replace_axes_with_cartopy_axes(cartopy_proj): ylabel=ax.get_ylabel(), ) else: + position = ax.get_position(original=True) _ = fig.add_axes( + position, projection=cartopy_proj, title=ax.get_title(), xlabel=ax.get_xlabel(), diff --git a/lib/iris/tests/unit/plot/test__replace_axes_with_cartopy_axes.py b/lib/iris/tests/unit/plot/test__replace_axes_with_cartopy_axes.py new file mode 100644 index 0000000000..c4416c587d --- /dev/null +++ b/lib/iris/tests/unit/plot/test__replace_axes_with_cartopy_axes.py @@ -0,0 +1,45 @@ +# Copyright Iris contributors +# +# This file is part of Iris and is released under the LGPL license. +# See COPYING and COPYING.LESSER in the root of the repository for full +# licensing details. +"""Unit tests for the `iris.plot.__replace_axes_with_cartopy_axes` function.""" + +# Import iris.tests first so that some things can be initialised before +# importing anything else. +import iris.tests as tests # isort:skip + +import cartopy.crs as ccrs +import matplotlib.pyplot as plt + +from iris.plot import _replace_axes_with_cartopy_axes + + +@tests.skip_plot +class Test_replace_axes_with_cartopy_axes(tests.IrisTest): + def setUp(self): + self.fig = plt.figure() + + def test_preserve_position(self): + position = [0.17, 0.65, 0.2, 0.2] + projection = ccrs.PlateCarree() + + plt.axes(position) + _replace_axes_with_cartopy_axes(projection) + result = plt.gca() + + # result should be the same as an axes created directly with the projection. + expected = plt.axes(position, projection=projection) + + # get_position returns mpl.transforms.Bbox object, for which equality does + # not appear to be implemented. Compare the bounds (tuple) instead. + self.assertEqual( + expected.get_position().bounds, result.get_position().bounds + ) + + def tearDown(self): + plt.close(self.fig) + + +if __name__ == "__main__": + tests.main()