Skip to content
Closed
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
17 changes: 9 additions & 8 deletions lib/cartopy/mpl/geoaxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
from cartopy.mpl.slippy_image_artist import SlippyImageArtist
from cartopy.vector_transform import vector_scalar_to_grid


assert mpl.__version__ >= '1.5.1', ('Cartopy is only supported with '
'Matplotlib 1.5.1 or greater.')

Expand Down Expand Up @@ -301,6 +300,7 @@ def set_position(self, position):

def _add_transform(func):
"""A decorator that adds and validates the transform keyword argument."""

@functools.wraps(func)
def wrapper(self, *args, **kwargs):
transform = kwargs.get('transform', None)
Expand All @@ -314,6 +314,7 @@ def wrapper(self, *args, **kwargs):

kwargs['transform'] = transform
return func(self, *args, **kwargs)

return wrapper


Expand Down Expand Up @@ -450,7 +451,7 @@ def hold_limits(self, hold=True):
self.dataLim.set_points(data_lim)
self.viewLim.set_points(view_lim)
(self.ignore_existing_data_limits,
self._autoscaleXon, self._autoscaleYon) = other
self._autoscaleXon, self._autoscaleYon) = other

def _draw_preprocess(self, renderer):
"""
Expand Down Expand Up @@ -654,7 +655,7 @@ def tissot(self, rad_km=500, lons=None, lats=None, n_samples=80, **kwargs):
raise ValueError('lons and lats must have the same shape.')

for lon, lat in zip(lons, lats):
circle = geod.circle(lon, lat, rad_km*1e3, n_samples=n_samples)
circle = geod.circle(lon, lat, rad_km * 1e3, n_samples=n_samples)
geoms.append(sgeom.Polygon(circle))

feature = cartopy.feature.ShapelyFeature(geoms, ccrs.Geodetic(),
Expand Down Expand Up @@ -1349,13 +1350,13 @@ def imshow(self, img, *args, **kwargs):
# kwargs['alpha'] is guaranteed to be either 1D, 2D, or None
alpha = kwargs.pop('alpha')
old_img = img[:, :, 0:3]
img = np.zeros(img.shape[:2] + (4, ), dtype=img.dtype)
img = np.zeros(img.shape[:2] + (4,), dtype=img.dtype)
img[:, :, 0:3] = old_img
# Put an alpha channel in if the image was masked.
if not np.any(alpha):
alpha = 1
img[:, :, 3] = np.ma.filled(alpha, fill_value=0) * \
(~np.any(old_img.mask, axis=2))
img[:, :, 3] = np.ma.filled(alpha, fill_value=0) * (
~np.any(old_img.mask, axis=2))
if img.dtype.kind == 'u':
img[:, :, 3] *= 255

Expand Down Expand Up @@ -1700,7 +1701,7 @@ def _pcolormesh_patched(self, *args, **kwargs):
collection.set_alpha(alpha)
collection.set_array(C)
if norm is not None:
assert(isinstance(norm, mcolors.Normalize))
assert (isinstance(norm, mcolors.Normalize))
collection.set_cmap(cmap)
collection.set_norm(norm)
collection.set_clim(vmin, vmax)
Expand Down Expand Up @@ -1782,7 +1783,7 @@ def _pcolormesh_patched(self, *args, **kwargs):
# projection which will help with curved boundaries
size_limit = (abs(self.projection.x_limits[1] -
self.projection.x_limits[0]) /
(2*np.sqrt(2)))
(2 * np.sqrt(2)))
to_mask = (np.isnan(diagonal0_lengths) |
(diagonal0_lengths > size_limit) |
np.isnan(diagonal1_lengths) |
Expand Down
25 changes: 23 additions & 2 deletions lib/cartopy/mpl/gridliner.py
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,16 @@ def _segment_angle_to_text_specs(self, angle, lonlat):
x=dx, y=dy, units='points')
kw.update(transform=transform)

if self.xpadding < 0 or self.ypadding < 0:
if kw['ha'] == 'left':
kw['ha'] = 'right'
elif kw['ha'] == 'right':
kw['ha'] = 'left'
if kw['va'] == 'top':
kw['va'] = 'bottom'
elif kw['va'] == 'bottom':
kw['va'] = 'top'

return kw, loc

def _update_labels_visibility(self, renderer):
Expand Down Expand Up @@ -783,6 +793,7 @@ def remove_path_dupes(path):
this_patch = artist.get_bbox_patch()
this_path = this_patch.get_path().transformed(
this_patch.get_transform())

if '3.1.0' <= matplotlib.__version__ <= '3.1.2':
this_path = remove_path_dupes(this_path)
center = artist.get_transform().transform_point(
Expand All @@ -803,17 +814,27 @@ def remove_path_dupes(path):
.transformed(self.axes.transData))
if '3.1.0' <= matplotlib.__version__ <= '3.1.2':
outline_path = remove_path_dupes(outline_path)

# Inline must be within the map.
if ((lonlat == 'lon' and self.x_inline) or
(lonlat == 'lat' and self.y_inline)):
# TODO: When Matplotlib clip path works on text, this
# clipping can be left to it.
if outline_path.contains_point(center):
visible = True
# Non-inline must not run through the outline.
elif not outline_path.intersects_path(this_path):
elif not outline_path.intersects_path(this_path,
False if
self.xpadding < 0 or
self.ypadding < 0
else True):
visible = True

# labels must be within map bbox
if (self.xpadding < 0 or self.ypadding < 0) and (
not this_path.intersects_path(
outline_path)):
visible = False

# Good
if visible:
break
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 54 additions & 1 deletion lib/cartopy/tests/mpl/test_gridliner.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,16 @@ def test_gridliner_specified_lines():
TOL = 15
else:
TOL = 0.5
grid_label_tol = grid_label_inline_tol = grid_label_inline_usa_tol = TOL
grid_label_tol = \
grid_label_inline_tol = \
grid_label_inline_usa_tol = \
grid_label_intersect_map_tol = TOL

grid_label_inline_tol += 1.1
grid_label_image = 'gridliner_labels'
grid_label_inline_image = 'gridliner_labels_inline'
grid_label_inline_usa_image = 'gridliner_labels_inline_usa'
grid_label_intersect_map_image = 'gridliner_labels_intersect_map'


@pytest.mark.natural_earth
Expand Down Expand Up @@ -388,3 +393,51 @@ def test_gridliner_line_limits():
for path in paths:
assert (np.min(path.vertices, axis=0) >= (xlim[0], ylim[0])).all()
assert (np.max(path.vertices, axis=0) <= (xlim[1], ylim[1])).all()


@pytest.mark.natural_earth

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

E302 expected 2 blank lines, found 1

@ImageTesting([grid_label_intersect_map_image],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need another 1 MB image comparison test? Or can this be checked by comparing against the positions of the labels and whether they are visible or not?

Or maybe just a single smaller image would be fine.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that could work. I'll make some new test tomorrow.

tolerance=grid_label_intersect_map_tol)
def test_grid_labels_intersect_map():
top = 49.3457868 # north lat
left = -124.7844079 # west long
right = -66.9513812 # east long
bottom = 24.7433195 # south lat
plt.figure(figsize=(35, 35))
for i, proj in enumerate(TEST_PROJS, 1):
if isinstance(proj, tuple):
proj, kwargs = proj
else:
kwargs = {}
ax = plt.subplot(7, 4, i, projection=proj(**kwargs))
try:
ax.set_extent([left, right, bottom, top], crs=ccrs.PlateCarree())
except Exception:
pass
ax.set_title(proj, y=1.075)
if ccrs.PROJ4_VERSION[:2] == (5, 0) and proj in (
ccrs.Orthographic,
ccrs.AlbersEqualArea,
ccrs.Geostationary,
ccrs.NearsidePerspective,
):
# Above projections are broken, so skip labels.
# Add gridlines anyway to minimize image differences.
ax.gridlines()
else:
gl = ax.gridlines(draw_labels=True, clip_on=True)
gl.xpadding = -5
gl.ypadding = -5
ax.coastlines(resolution="110m")
plt.subplots_adjust(wspace=0.35, hspace=0.35)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

W391 blank line at end of file


def test_setting_padding_values():
plt.figure()
ax = plt.subplot(1, 1, 1, projection=ccrs.PlateCarree())
gl = ax.gridlines()
assert gl.xpadding == 5 and gl.ypadding == 5
gl.xpadding = gl.ypadding = 10
assert gl.xpadding == 10 and gl.ypadding == 10
gl.xpadding = gl.ypadding = -5
assert gl.xpadding == -5 and gl.ypadding == -5