cartopy 绘制中国地图,南海诸岛和十段线

cartopy作为Basemap的替代者,绘制地图还是非常方便的,尤其是有很多大牛现成的例子,这里参考了多篇文章,结合了绘制dat格式和shp格式的边界方法,使用了GMT中文社区的中国边界,shp文件为Meteo-Python群共享资源,资源已上传给出。
需要注意几点:

  1. 网上的中国区域shp文件很多有问题,藏南,台湾,钓鱼岛等区域不全,要小心使用。
  2. dat格式文件中有的有注释,读取时需要处理。
  3. shp文件的加载有多种方法,经验证文中两种方法都有效。
  4. cartopy处理跨越180度经线的范围时需要特别注意,设置central_longitude参数。
  5. shp文件会覆盖掉cartopy的河流,湖泊等元素,要在绘制shp文件后再加载。
  6. 经纬度网格和标签格式设置较麻烦。
# coding:utf-8
__author__ = 'JSBZS-tanmch'
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
import cartopy.io.shapereader as shapereader
import matplotlib.ticker as mticker

# 从文件中加载中国国界、省界和十段线数据,
# https://gmt-china.org/data/CN-border-La.dat
with open(r'D:\PYcharmProjects\TyphoonCartopy\CN-border-La.dat') as src:
    context = ''.join([line for line in src if not line.startswith('#')])
    blocks = [cnt for cnt in context.split('>') if len(cnt) > 0]
    borders = [np.fromstring(block, dtype=float, sep=' ') for block in blocks]
#从文件中加载中国区域shp
shpfile = shapereader.Reader(r'D:\PYcharmProjects\TyphoonCartopy\borders_shp_dat\extracted\china_country.shp')

# 设置 figure 大小
fig = plt.figure(figsize=[8, 5.5])
# 设置投影方式并绘制主图
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
# 添加海洋,陆地,河流,湖泊,国界线和海岸线。
ax.add_feature(cfeature.OCEAN.with_scale('50m'))
ax.add_feature(cfeature.LAND.with_scale('50m'))
# ax.add_feature(cfeature.RIVERS.with_scale('50m'))
# ax.add_feature(cfeature.LAKES.with_scale('50m'))
ax.add_feature(cfeature.BORDERS.with_scale('50m'),lw=0.5)
ax.add_feature(cfeature.COASTLINE.with_scale('50m'),lw=0.5)
# 加载中国区域shp
#--------------方法一------------
# shape_feature = cfeature.ShapelyFeature(shpfile.geometries(),
#                                 ccrs.PlateCarree(), facecolor='teal')
# ax.add_feature(shape_feature)
#--------------方法二------------
for rec in shpfile.records():
    ax.add_geometries([rec.geometry], crs=ccrs.PlateCarree(),facecolor='red')
# 绘制中国边界和十段线
for line in borders:
    ax.plot(line[0::2], line[1::2], '-', lw=1, color='k',transform=ccrs.Geodetic())
ax.add_feature(cfeature.RIVERS.with_scale('50m'))
ax.add_feature(cfeature.LAKES.with_scale('50m'))
# 画经纬度网格
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=False, linewidth=1.2, color='k', alpha=0.5, linestyle='--')
gl.xlabels_top = False  # 关闭顶端的经纬度标签
gl.ylabels_right = False  # 关闭右侧的经纬度标签
gl.xformatter = LONGITUDE_FORMATTER  # x轴设为经度的格式
gl.yformatter = LATITUDE_FORMATTER  # y轴设为纬度的格式
#设置经纬度网格的间隔
gl.xlocator = mticker.FixedLocator(np.arange(70, 140+10, 10))
gl.ylocator = mticker.FixedLocator(np.arange(0, 55+10, 10))
# 设置显示范围
ax.set_extent([70, 140, 0, 55],crs=ccrs.PlateCarree())
#设置坐标标签
ax.set_xticks(list(range(70,140,10)), crs=ccrs.PlateCarree())
ax.set_yticks(list(range(0,55,10)), crs=ccrs.PlateCarree())
# zero_direction_label用来设置经度的0度加不加E和W
lon_formatter = LongitudeFormatter(zero_direction_label=False)
lat_formatter = LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)
plt.show()

效果如下图:
cartopy 绘制中国地图,南海诸岛和十段线_第1张图片

你可能感兴趣的:(笔记)