Search code examples
pythoncartopy

Cartopy: wrong longitude labels when plotting regional maps


I tried to plot regional map between 119degE and 90degW but something wrong with my longitude labels. Here is my attempt:

import numpy as np
import cartopy.crs as ccrs
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
from matplotlib import pyplot as plt

lats = -31
latn =  31
lon1 = 119  
lon2 = 301   

plt.figure()                            
proj = ccrs.PlateCarree(central_longitude=210)    
ax = plt.axes(projection=proj)   
ax.set_extent([lon1, lon2, lats, latn], proj)  
ax.coastlines()                   
ax.set_xticks(np.arange(120,330,30) ,crs=ccrs.PlateCarree())
ax.set_yticks(np.arange(-30, 40,10) ,crs=ccrs.PlateCarree()) 
lon_formatter = LONGITUDE_FORMATTER
lat_formatter = LATITUDE_FORMATTER
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)     

ax.set_ylabel(' ')   
ax.set_xlabel(' ')
plt.show()

The result: enter image description here

Here are the problems:

  1. I set ax.set_extent with longitude range given by lon1 and lon2. But the figure shows the global longitude.
  2. The longitude tick labels are wrong (should be 120E, 150E, 180, 150W, ...).

How to fix these issues?

The version of cartopy I use is v0.20.0.


Solution

  • Use gridlines() function with proper settings. Note, the option crs=ccrs.PlateCarree() is used in the function to get correct geographic longitudes.

    import numpy as np
    import cartopy.crs as ccrs
    from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
    from matplotlib import pyplot as plt
    
    lats = -31
    latn =  31
    lon1 = 119  
    lon2 = 301   
    
    plt.figure(figsize=[9,6])                            
    proj = ccrs.PlateCarree(central_longitude=210)    
    ax = plt.axes(projection=proj)   
    ax.set_extent([lon1, lon2, lats, latn], proj)  
    ax.coastlines()
    
    gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, 
                      xlocs=np.arange(-150,360,30), ylocs=np.arange(-30, 40,10), 
                      x_inline=False, y_inline=False, linewidth=0.33, color='k',alpha=0.5)
    gl.right_labels = False
    gl.top_labels = False
    
    ax.set_ylabel(' ')   
    ax.set_xlabel(' ')
    plt.show()
    

    world