无敌了!python中国地图绘制模板,含九段线,南海诸岛,还不收藏的都是神人了

文摘   2024-12-23 22:15   北京  

python cartopy绘制子图九段线,南海诸岛

今天给大家介绍如何使用 「Cartopy」 绘制一张高质量的中国地图,带上九段线和南海诸岛子图。看完这篇文章,你不仅能绘制出专业的地图,还能轻松地处理各种矢量和栅格数据!赶紧收藏!

「1. 先准备数据」

绘制地图的第一步是准备数据。在这里,我们需要两种数据:

  1. 「降水格点栅格数据」:作为示例数据,可以显示中国的降水分布;
  2. 「矢量数据」:包括中国省界 shapefile 和九段线 shapefile,用于精确绘制边界。

栅格数据准备

降水数据可以通过多个开源平台获取,例如 中国气象局数据开放平台。下载的降水格点数据可以通过以下代码处理,提取并计算月降水总量的均值栅格:

import pandas as pd
import numpy as np
import os
dir = 'D:/Acdemic/xibei/data_1/grid_prcp/'
txtLists = os.listdir(dir)
files = list(filter(lambda x: x[-4:] in ['.txt'], txtLists))
df = pd.DataFrame()
i = 0;
prcp = np.zeros((72128, len(files)))
for file in files:
    data = pd.read_table(dir+file, sep='\s+', header=None, index_col=False, skiprows=6)
    print(str(i) + ': ' + file)
    prcp[:, :, i] = np.array(data)
    i += 1
prcp1 = np.mean(prcp, 2) * 12
prcp1[prcp1 < -1000] = None

矢量数据准备

我们需要两个矢量文件:

  1. 中国省界矢量(china.shp);
  2. 九段线矢量(dashline.shp)。

定义两个辅助函数,方便在绘图中加载这些数据:

import cartopy.io.shapereader as shpreader
def add_china(ax, **kwargs):
    '''
    在地图上画出中国省界的shapefile.

    Parameters
    ----------
    ax : GeoAxes
        目标地图.

    **kwargs
        绘制shape时用到的参数.例如linewidth,edgecolor和facecolor等.
    '''

    proj = ccrs.PlateCarree()
    reader = shpreader.Reader('D:/OneDrive/data/china.shp')
    provinces = reader.geometries()
    ax.add_geometries(provinces, proj, **kwargs)
    reader.close()
    
def add_dashline(ax, **kwargs):
    '''
    在地图上画出中国省界的shapefile.

    Parameters
    ----------
    ax : GeoAxes
        目标地图.

    **kwargs
        绘制shape时用到的参数.例如linewidth,edgecolor和facecolor等.
    '''

    proj = ccrs.PlateCarree()
    reader = shpreader.Reader(r"D:\OneDrive\data\dashline.shp")
    provinces = reader.geometries()
    ax.add_geometries(provinces, proj, **kwargs)
    reader.close()

矢量文件的下载链接见文末,记得保存到本地,并修改路径。


「2. 开始绘图」

绘图中,我们将使用 Cartopy「Lambert Conformal 投影」 来绘制中国地图,同时在子图中展示南海诸岛及九段线。

import geopandas as gpd 
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
projn = ccrs.LambertConformal(central_longitude=105
                              central_latitude=40,
                              standard_parallels=(25.047.0))

fig = plt.figure(figsize=(4,3.5),dpi=120,facecolor="w")
ax = fig.add_subplot(projection=projn)
ax.add_feature(cfeature.LAND, facecolor='white')
ax.add_feature(cfeature.OCEAN)
ax.add_feature(cfeature.LAKES.with_scale('110m'), facecolor='#BEE8FF')
ax.set_extent([701401555], crs=ccrs.PlateCarree())
long = np.linspace(72136128); lat = np.linspace(185472)
im = ax.contourf(
    long, lat[::-1], prcp1,
    levels=np.linspace(0200011), cmap='RdYlBu_r',
    extend='both', alpha=0.8, transform=ccrs.PlateCarree()
)
cbar = fig.colorbar(
    im, ax=ax, shrink=0.9, pad=0.1, orientation='horizontal'
)
#添加geopandas 读取的地理文件
add_dashline(ax, ec="black", linewidth=.2)
add_china(ax, ec="black", fc="None", linewidth=.2)
gls = ax.gridlines(draw_labels=True, crs=ccrs.PlateCarree(), 
                   color='k', linestyle='dashed', linewidth=0.3
                   y_inline=False, x_inline=False,
                   xlocs=range(70,150,10), ylocs=range(15,65,10)
                  )
#gls.top_labels= False                      
#gls.right_labels=False
ax2 = fig.add_axes([0.760.2650.200.3], projection = projn)
ax2.set_extent([104.5125026])
im = ax2.contourf(
    long, lat[::-1], prcp1,
    levels=np.linspace(0200011), cmap='RdYlBu_r',
    extend='both', alpha=0.8, transform=ccrs.PlateCarree()
)
ax2.set_facecolor('#BEE8FF')
ax2.spines['geo'].set_linewidth(.2)
# 设置网格点
lb=ax2.gridlines(draw_labels=False,x_inline=False, y_inline=False,
                 linewidth=0.1, color='gray', alpha=0.8
                 linestyle='--' )
add_dashline(ax2, ec="black", linewidth=.2)
add_china(ax2, ec="black", fc="None", linewidth=.2)
ax2.add_feature(cfeature.LAND, facecolor='w')
plt.tight_layout()
plt.show()

「3. 结果展示」

最终的结果如下图所示:

完整地图

「代码解析」

核心步骤解读:

  1. 「投影设置」projn = ccrs.LambertConformal(...),Lambert 正形投影适合中国地图显示,能避免纬度偏差造成的视觉问题。
  2. 「绘制背景」:使用 ax.add_feature 添加陆地、海洋和湖泊特征,颜色和风格可自定义。
  3. 「栅格数据叠加」:利用 ax.contourf 绘制降水分布图,并设置色彩范围和透明度。
  4. 「矢量边界」:自定义函数 add_chinaadd_dashline,通过 shapefile 精确绘制省界和九段线。
  5. 「南海诸岛子图」:子图通过 fig.add_axes 添加,独立设置绘图范围和投影,同样支持栅格与矢量叠加。
  6. 「美化细节」:添加网格、色条和样式优化,提升地图可读性。

「4. 数据获取和说明」

  • 「降水数据」:CMA 数据开放平台;http://data.cma.cn
  • 矢量数据:
    • 中国省界矢量:Data Source;https://github.com/datasets/geo-boundaries-world-110m
    • 九段线矢量:参考 South China Sea Dashline。https://github.com/datasets/geo-boundaries-world-110m

「结语」

掌握了这套模板,你可以轻松绘制出带九段线和南海子图的中国地图,并添加任意的栅格或矢量数据进行展示!如果觉得有用,赶紧点赞收藏!🎉

求求你点个在看吧,这对我真的很重要


地学万事屋
分享先进Matlab、R、Python、GEE地学应用,以及分享制图攻略。
 最新文章