使用 Cartopy 添加网格线

Adding gridlines using Cartopy

我正在尝试将网格线添加到我使用 Cartopy 制作的地图中,但是,当我使用来自 cartopy 文档的示例代码时,它没有显示我想要的内容,我不知道如何操纵它来做到这一点。

def plotMap():

    proj = ccrs.Mercator(central_longitude=180, min_latitude=15, 
    max_latitude=55)

    fig, ax = plt.subplots(subplot_kw=dict(projection=proj), figsize=(12,12))

    ax.set_extent([255 ,115, 0, 60], crs=ccrs.PlateCarree())

    ax.add_feature(cfeature.LAND, facecolor='0.3')
    ax.add_feature(cfeature.LAKES, alpha=0.9)  
    ax.add_feature(cfeature.BORDERS, zorder=10)
    ax.add_feature(cfeature.COASTLINE, zorder=10)


    #(http://www.naturalearthdata.com/features/)
    states_provinces = cfeature.NaturalEarthFeature(
            category='cultural',  name='admin_1_states_provinces_lines',
            scale='50m', facecolor='none')
    ax.add_feature(states_provinces, edgecolor='black', zorder=10)

    #ax.gridlines(xlocs=grids_ma, ylocs=np.arange(-80,90,20), zorder=21, 
    draw_labels=True ) 
    ax.gridlines(crs=ccrs.PlateCarree(), linewidth=2, color='black', 
    draw_labels=True, alpha=0.5, linestyle='--')
    ax.xlabels_top = False
    ax.ylabels_left = False
    ax.ylabels_right=True
    ax.xlines = True
    ax.xlocator = mticker.FixedLocator([-160, -140, -120, 120, 140, 160, 180,])
    ax.xformatter = LONGITUDE_FORMATTER
    ax.yformatter = LATITUDE_FORMATTER
    ax.xlabel_style = {'size': 15, 'color': 'gray'}
    ax.xlabel_style = {'color': 'red', 'weight': 'bold'}


    return fig, ax

我附上了输出图片。作为参考,我只希望经度网格线从我域的左侧开始并在右侧结束,最好每 20 度间隔一次。理想情况下,纬度线也相同。 Bad gridline plot

您使用的示例是 this page 底部的示例吗?如果是这样,您正试图在 GeoAxes (ax) 实例上设置应该在 GridLiner (gl) 实例上设置的属性:

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

from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER

def plotMap():    
    proj = ccrs.Mercator(central_longitude=180, min_latitude=15, 
    max_latitude=55)

    fig, ax = plt.subplots(subplot_kw=dict(projection=proj), figsize=(12,12))

    ax.set_extent([255 ,115, 0, 60], crs=ccrs.PlateCarree())

    ax.add_feature(cfeature.LAND, facecolor='0.3')
    ax.add_feature(cfeature.LAKES, alpha=0.9)  
    ax.add_feature(cfeature.BORDERS, zorder=10)
    ax.add_feature(cfeature.COASTLINE, zorder=10)

    states_provinces = cfeature.NaturalEarthFeature(
            category='cultural',  name='admin_1_states_provinces_lines',
            scale='50m', facecolor='none')
    ax.add_feature(states_provinces, edgecolor='black', zorder=10)   

    gl = ax.gridlines(crs=ccrs.PlateCarree(), linewidth=2, color='black', alpha=0.5, linestyle='--', draw_labels=True)
    gl.xlabels_top = False
    gl.ylabels_left = False
    gl.ylabels_right=True
    gl.xlines = True
    gl.xlocator = mticker.FixedLocator([120, 140, 160, 180, -160, -140, -120])
    gl.ylocator = mticker.FixedLocator([0, 20, 40, 60])
    gl.xformatter = LONGITUDE_FORMATTER
    gl.yformatter = LATITUDE_FORMATTER
    gl.xlabel_style = {'color': 'red', 'weight': 'bold'}

这将生成以下地图。 gridliner 似乎无法应对日期变更线。我不知道是否有办法解决这个问题,但上面链接文档的顶部有一条注释说目前已知此 class 存在限制,所以可能没有。

另一种方法是直接使用 matplotlib 设置各种标签及其样式。请注意,您必须将刻度标签与刻度分开设置,否则您将获得对应于墨卡托坐标参考系统的标签:

import cartopy.mpl.ticker as cticker

def plotMap2():
    proj = ccrs.Mercator(central_longitude=180, min_latitude=15, 
    max_latitude=55)

    fig, ax = plt.subplots(subplot_kw=dict(projection=proj), figsize=(12,12))

    ax.set_extent([255 ,115, 0, 60], crs=ccrs.PlateCarree())

    ax.add_feature(cfeature.LAND, facecolor='0.3')
    ax.add_feature(cfeature.LAKES, alpha=0.9)  
    ax.add_feature(cfeature.BORDERS, zorder=10)
    ax.add_feature(cfeature.COASTLINE, zorder=10)

    states_provinces = cfeature.NaturalEarthFeature(
            category='cultural',  name='admin_1_states_provinces_lines',
            scale='50m', facecolor='none')
    ax.add_feature(states_provinces, edgecolor='black', zorder=10)

    ax.set_xticks([120., 140., 160., 180., -160., -140., -120.], crs=ccrs.PlateCarree())
    ax.set_xticklabels([120., 140., 160., 180., -160., -140., -120.], color='red', weight='bold')
    ax.set_yticks([20, 40], crs=ccrs.PlateCarree())
    ax.set_yticklabels([20, 40])
    ax.yaxis.tick_right()

    lon_formatter = cticker.LongitudeFormatter()
    lat_formatter = cticker.LatitudeFormatter()
    ax.xaxis.set_major_formatter(lon_formatter)
    ax.yaxis.set_major_formatter(lat_formatter)
    ax.grid(linewidth=2, color='black', alpha=0.5, linestyle='--')