pythoncartopy

Issue with Cartopy automatically resetting extent when adding data


I am trying to map some data with Cartopy but I am experiencing issues with the map extent. When plotting the map on itself Cartopy displays the entire globe (that's great, that's what I want):

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature


# Initialise plot
cm = 1/2.54
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(15*cm, 8*cm),
                       subplot_kw={'projection': ccrs.Mollweide()})

# Add land
ax.add_feature(cfeature.NaturalEarthFeature(category='physical',
                                            name='land',
                                            scale='50m'),
               facecolor='#ccc',
               edgecolor='black',
               linewidth=.25,
               zorder=1)

# Export
fpath = "figures/test_map1.png"
fig.savefig(fpath, format='png', bbox_inches='tight', dpi=300)

enter image description here

But when adding some data (e.g., as scatter), Cartopy automatically resets the scale to show only the geographic area occupied by the data:

# Create and plot dummy data
xv = [*range(-50, 0)]
yv = [*range(-20, 30)]
ax.scatter(xv,
           yv,
           edgecolor='red',
           s=20,
           marker='.',
           linewidth=2,
           transform=ccrs.PlateCarree(),
           zorder=0)
fpath = "figures/test_map2.png"
fig.savefig(fpath, format='png', bbox_inches='tight', dpi=300)

enter image description here

That would be ok if resetting it back manually wouldn't be tricky: set_extent() does not work if longitude limits are set to -180, 180 (the map disappears, I understand that due to limit issues), and setting -179.9999, 179.9999 leaves small cuts at the sides:

# Try to reset extent
ax.set_extent([-179.9999, 179.9999, -90, 90], crs=ccrs.PlateCarree())
fpath = "figures/test_map3.png"
fig.savefig(fpath, format='png', bbox_inches='tight', dpi=300)

enter image description here

enter image description here

My problem gets worse with other projections, e.g., NearsidePerspective, as it's not straightforward to me how to know the maximum extent that they accept [The Cartopy documentation on projections does not address this matter as far as I'm aware]. For instance, setting extent to [-90, 90, -90, 90] with the NearsidePerspective projection returns the following error:

ValueError: Axis limits cannot be NaN or Inf

And setting more restricted extents produces unsatisfactory results (i.e., again, border cuts):

fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(15*cm, 8*cm),
                       subplot_kw={'projection': ccrs.NearsidePerspective(
                           central_longitude=0,
                           central_latitude=0
                           )})
ax.add_feature(cfeature.NaturalEarthFeature(category='physical',
                                            name='land',
                                            scale='50m'),
               facecolor='#ccc',
               edgecolor='black',
               linewidth=.25,
               zorder=1)
ax.scatter(xv,
           yv,
           edgecolor='red',
           s=20,
           marker='.',
           linewidth=2,
           transform=ccrs.PlateCarree(),
           zorder=0)
ax.set_extent([-70, 70, -60, 60], crs=ccrs.PlateCarree())
fpath = "figures/test_map4.png"
fig.savefig(fpath, format='png', bbox_inches='tight', dpi=300)

enter image description here

I have also tried changing the figure size and proportions, but it does not seem to work. So, my questions would be:

  1. Is there a way to avoid the automatic reset of limits in the first place?
  2. If not, what would be the appropriate way to deal with it given the aforementioned issues?

Solution

  • Quoting a comment from the classic Global Map example :

    # make the map global rather than have it zoom in to
    # the extents of any plotted data
    ax.set_global()
    

    And indeed, adding set_global before the scatter seems to fix your issue (see full code):

    enter image description here