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)
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)
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)
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)
I have also tried changing the figure size and proportions, but it does not seem to work. So, my questions would be:
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):