Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include gridliner labels in tight bbox calculation #1355

Merged
merged 6 commits into from
Jul 1, 2020
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
38 changes: 29 additions & 9 deletions lib/cartopy/mpl/geoaxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,19 +430,13 @@ def hold_limits(self, hold=True):
(self.ignore_existing_data_limits,
self._autoscaleXon, self._autoscaleYon) = other

@matplotlib.artist.allow_rasterization
def draw(self, renderer=None, **kwargs):
def _draw_preprocess(self, renderer):
"""
Extend the standard behaviour of :func:`matplotlib.axes.Axes.draw`.

Draw grid lines and image factory results before invoking standard
Matplotlib drawing. A global range is used if no limits have yet
been set.

Perform pre-processing steps shared between :func:`GeoAxes.draw`
and :func:`GeoAxes.get_tightbbox`.
"""
# If data has been added (i.e. autoscale hasn't been turned off)
# then we should autoscale the view.

if self.get_autoscale_on() and self.ignore_existing_data_limits:
self.autoscale_view()

Expand All @@ -454,6 +448,32 @@ def draw(self, renderer=None, **kwargs):
for gl in self._gridliners:
gl._draw_gridliner(renderer=renderer)

def get_tightbbox(self, renderer, *args, **kwargs):
"""
Extend the standard behaviour of
:func:`matplotlib.axes.Axes.get_tightbbox`.

Adjust the axes aspect ratio, background patch location, and add
gridliners before calculating the tight bounding box.
"""
# Shared processing steps
self._draw_preprocess(renderer)

return matplotlib.axes.Axes.get_tightbbox(
self, renderer, *args, **kwargs)

@matplotlib.artist.allow_rasterization
def draw(self, renderer=None, **kwargs):
"""
Extend the standard behaviour of :func:`matplotlib.axes.Axes.draw`.

Draw grid lines and image factory results before invoking standard
Matplotlib drawing. A global range is used if no limits have yet
been set.
"""
# Shared processing steps
self._draw_preprocess(renderer)

# XXX This interface needs a tidy up:
# image drawing on pan/zoom;
# caching the resulting image;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 46 additions & 0 deletions lib/cartopy/tests/mpl/test_gridliner.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ def test_gridliner_specified_lines():
grid_label_inline_tol = 6.4
grid_label_inline_usa_tol = 4.0
else:
# Skip test_grid_labels_tight for matplotlib 1.5.1 because it
# is not possible to override tight bounding box calculation
grid_label_image = 'gridliner_labels_1.5'
grid_label_tol = 1.8
grid_label_inline_image = 'gridliner_labels_inline_1.5'
Expand Down Expand Up @@ -234,6 +236,50 @@ def test_grid_labels():
plt.subplots_adjust(wspace=0.25, hspace=0.25)


@pytest.mark.skipif(
MPL_VERSION < '2.0.0',
reason='Impossible to override tight layout algorithm in mpl < 2.0.0')
@pytest.mark.natural_earth
@ImageTesting(['gridliner_labels_tight'], tolerance=grid_label_tol)
def test_grid_labels_tight():

# Ensure tight layout accounts for gridlines
fig = plt.figure(figsize=(7, 5))

crs_pc = ccrs.PlateCarree()
crs_merc = ccrs.Mercator()

ax = fig.add_subplot(2, 2, 1, projection=crs_pc)
ax.coastlines(resolution="110m")
ax.gridlines(draw_labels=True)

ax = fig.add_subplot(2, 2, 2, projection=crs_merc)
ax.coastlines(resolution="110m")
ax.gridlines(draw_labels=True)

# Matplotlib tight layout is also incorrect if cartopy fails
# to adjust aspect ratios first. Relevant when aspect ratio has
# changed due to set_extent.
ax = fig.add_subplot(2, 2, 3, projection=crs_pc)
ax.set_extent([-20, 10.0, 45.0, 70.0])
ax.coastlines(resolution="110m")
ax.gridlines(draw_labels=True)

ax = fig.add_subplot(2, 2, 4, projection=crs_merc)
ax.set_extent([-20, 10.0, 45.0, 70.0], crs=crs_pc)
ax.coastlines(resolution="110m")
gl = ax.gridlines(draw_labels=True)
gl.rotate_labels = False

# Apply tight layout
fig.tight_layout()

# Ensure gridliners were plotted
for ax in fig.axes:
for gl in ax._gridliners:
assert hasattr(gl, '_plotted') and gl._plotted


@pytest.mark.natural_earth
@ImageTesting([grid_label_inline_image], tolerance=grid_label_inline_tol)
def test_grid_labels_inline():
Expand Down