Search code examples
pythonmatplotlibgridlabelcartopy

How can I create circular grid line labels for a South Polar Stereo projection?


I'm using the South Polar Stereographic projection to create a map of Antarctica. I've been able to create the gridlines using Cartopy, but the labels for the gridlines are not circular around the map, which is what I want. Is there a way to make the gridline labels follow the circular pattern of the South Polar Stereographic projection? Here's the code I'm currently using:

fig = plt.figure(figsize=(12,8))
ax = plt.axes(projection=ccrs.SouthPolarStereo())
ax.set_extent([-180, 180, -90, -30], ccrs.PlateCarree())
ax.add_feature(cfeature.LAND, color='darkgrey')
ax.add_feature(cfeature.OCEAN, color='lightblue')
ax.add_feature(cfeature.COASTLINE, linewidth=1.25)

# Make the gridlines circular
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=1, color='gray', alpha=0.5, linestyle='--', zorder=10)

# Add circular boundary
theta = np.linspace(0, 2*np.pi, 100)
center, radius = [0.5, 0.5], 0.5
verts = np.vstack([np.sin(theta), np.cos(theta)]).T
circle = mpath.Path(verts * radius + center)

ax.set_boundary(circle, transform=ax.transAxes)

plt.tight_layout()
plt.show()

The output looks like enter image description here

enter image description here


Solution

  • Here is the solution. This requires 2 gridlines() statements to achieve the required plot.

    import cartopy.crs as ccrs
    import cartopy.feature as cfeature
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.patches as  mpath
    
    fig = plt.figure(figsize=(12,8))
    ax = plt.axes(projection=ccrs.SouthPolarStereo())
    ax.set_extent([-180, 180, -90, -30], ccrs.PlateCarree())
    ax.add_feature(cfeature.LAND, color='darkgrey')
    ax.add_feature(cfeature.OCEAN, color='lightblue')
    ax.add_feature(cfeature.COASTLINE, linewidth=1.25)
    
    # Draw meridian lines with labels around circular boundary
    ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=1, \
                    xlocs=range(-180,171,10), ylocs=[], \
                    color='gray', alpha=0.5, linestyle='--', zorder=10)
    # Draw concentric circles (but hide labels) for the parallels of the latitude
    ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1, \
                    xlocs=[], ylocs=None, \
                    color='gray', alpha=0.5, linestyle='--', zorder=10)
    
    # Add circular boundary
    theta = np.linspace(0, 2*np.pi, 100)
    center, radius = [0.5, 0.5], 0.5
    verts = np.vstack([np.sin(theta), np.cos(theta)]).T
    circle = mpath.Path(verts * radius + center)
    
    ax.set_boundary(circle, transform=ax.transAxes)
    
    
    plt.tight_layout()
    plt.show()
    

    outputplot

    Edit

    For the labels around the map's border. Only manual plot is possible. I have been able to come up with this plot. But the code is very messy that I can't post it here until it is refined. Sorry about that.

    plot2