Python绘制中国地图
•
Python
1. 导入库
import cartopy import numpy as np import pandas as pd import proplot as pplt import geopandas as gpd import matplotlib.pyplot as plt from proplot import rc import cartopy.crs as ccrs import cartopy.feature as cfeature import matplotlib.path as mpath import cmaps seis = cmaps.GMT_seis # 导出指北针的库 import gma import gma.extend.mapplottools as mpt import gma.extend.arrayenhancement as aec # 导入自定义色带 from colormaps import parula rc["font.family"] = "TeX Gyre Schola" rc['tick.labelsize'] = 10 rc["axes.labelsize"] = 12 rc["axes.labelweight"] = "light" rc["tick.labelweight"] = "light"
2. 导入数据
# 加载数据 import geopandas as gpd file = r".\China map\中国省级地图GS(2019)1719号.geojson" nine = r".\China map\九段线GS(2019)1719号.geojson" china_main = gpd.read_file(file) china_nine = gpd.read_file(nine) china_main.head() china_shp = "./nc data/Data_ipynb/country1" from netCDF4 import Dataset import xarray as xr nc_file = r".\nc data\EC-Interim_monthly_2018.nc" ds = xr.open_dataset(nc_file) lat = ds.latitude lon = ds.longitude data = (ds['t2m'][0,::-1,:] - 273.15) # 把温度转换为℃
3. 南海九段线部分数据预处理
开始绘图之前需进行数据选择,即中国区域的数据,特别是绘制南海小地图的更需要,可避免一些问题(小地图上方出现完整地图)
#中国整体范围 lon_range1=lon[(lon>=70)&(lon=3)&(lat=104)&(lon=0)&(lat<=27)] china_full = data.sel(longitude=lon_range1,latitude=lat_range1) china_sub = data.sel(longitude=lon_range2,latitude=lat_range2) china_full_lon = china_full.longitude.values china_full_lat = china_full.latitude.values china_full_data = china_full.values china_sub_lon = china_sub.longitude.values china_sub_lat = china_sub.latitude.values china_sub_data = china_sub.values levels = np.arange(-25, 25 + 1, 1)
4. 定义掩膜方法,从全球的nc数据中,裁出中国地图部分的数据(根据shp文件裁剪nc数据)
def maskout_areas(originfig, ax, shp_path, proj=None):
import shapefile
import cartopy.crs as ccrs
from matplotlib.path import Path
#from cartopy.mpl.clip_path
from matplotlib.patches import PathPatch
#sf = shapefile.Reader(shp_path)
sf = shapefile.Reader(shp_path,encoding='gbk')
vertices = []
codes = []
for shape_rec in sf.shapeRecords():
if shape_rec.record[2] == 'China':
pts = shape_rec.shape.points
prt = list(shape_rec.shape.parts) + [len(pts)]
for i in range(len(prt) - 1):
for j in range(prt[i], prt[i + 1]):
if proj:
vertices.append(proj.transform_point(pts[j][0], pts[j][1], ccrs.Geodetic()))
else:
vertices.append((pts[j][0], pts[j][1]))
codes += [Path.MOVETO]
codes += [Path.LINETO] * (prt[i + 1] - prt[i] - 2)
codes += [Path.CLOSEPOLY]
clip = Path(vertices, codes)
clip = PathPatch(clip, transform=ax.transData)
for contour in originfig.collections:
contour.set_clip_path(clip)
5. 绘制填色地图
levels = np.arange(-25, 25 + 1, 1)
projn = ccrs.LambertConformal(central_longitude=107.5,
central_latitude=36,
standard_parallels=(25.0, 47.0)
)
fig = plt.figure(figsize=(4,3.5),dpi=120,facecolor="w")
ax = fig.add_subplot(projection=projn)
# cs = data.plot.contourf(ax=ax,levels=levels,cbar_kwargs=cbar_kwargs,
# cmap=parula,transform=ccrs.PlateCarree(),
# )
#自定义colorbar 参数
cs = china_full.plot.contourf(ax=ax,levels=levels,add_colorbar=False,
cmap=parula,transform=ccrs.PlateCarree(),
)
# #basemask(ax=ax, cs=cs,shp=china_shp)
maskout_areas(originfig=cs,ax=ax,shp_path=china_shp,proj=projn)
ax.set_facecolor('#BEE8FF')
ax.spines['geo'].set_linewidth(0.5)
#ax.stock_img()
ax.set_extent([80, 130, 16, 52.5], crs=ccrs.PlateCarree())
ax.coastlines(linewidth=0.3,zorder=20)
ax.add_feature(cfeature.LAND, facecolor='white')
ax.add_feature(cfeature.LAKES.with_scale('110m'), facecolor='#BEE8FF')
#添加geopandas 读取的地理文件
ax.add_geometries(china_main["geometry"],crs=ccrs.PlateCarree(),
fc="None",ec="k",linewidth=.2)
ax.add_geometries(china_nine["geometry"],crs=ccrs.PlateCarree(),
fc="None",ec="black",linewidth=.3)
#设置标题
ax.set_title("Example Of China Lambert Projection")
gls = ax.gridlines(draw_labels=True, crs=ccrs.PlateCarree(),
color='gray', linestyle='dashed', linewidth=0.2,
y_inline=False, x_inline=False,
rotate_labels=0,xpadding=5,
xlocs=range(-180,180,10), ylocs=range(-90,90,5),
xlabel_style={"size":8,"weight":"bold"},
ylabel_style={"size":8,"weight":"bold"}
)
gls.top_labels= False
gls.right_labels=False
#添加南海小地图
# 定位南海子图的位置,四个数字需要调整
# 四个数字分别是(left, bottom, width, height):
# 子图左下角水平方向相对位置,左下角垂直方向相对位置,子图宽,子图高
ax2 = fig.add_axes([0.74, 0.24, 0.1, 0.25], projection = projn)
ax2.set_extent([104.5, 124, 0, 26],crs=ccrs.PlateCarree())
#ax2.set(xlim=(104.5, 125),ylim=(0, 26))
ax2.set_facecolor('#BEE8FF')
ax2.spines['geo'].set_linewidth(0.4)
cs2 = china_sub.plot.contourf(ax=ax2,levels=levels,add_colorbar=False,
cmap=parula,transform=ccrs.PlateCarree(),
)
#basemask(ax=ax2, cs=cs2,shp=china_shp)
maskout_areas(originfig=cs2,ax=ax2,shp_path=china_shp,proj=projn)
ax2.set_title("")
# 设置网格点
lb=ax2.gridlines(draw_labels=False,x_inline=False, y_inline=False,
linewidth=0.1, color='gray', alpha=0.8,
linestyle='--' )
ax2.add_geometries(china_main["geometry"],crs=ccrs.PlateCarree(),
fc="None",ec="k",linewidth=.3)
ax2.add_geometries(china_nine["geometry"],crs=ccrs.PlateCarree(),
fc="None",ec="black",linewidth=.5)
ax2.add_feature(cfeature.LAND, facecolor='w')
## n.1 添加指北针
mpt.AddCompass(ax, LOC = (0.07, 0.86), SCA = 0.04, FontSize = 8)
## n.2 添加比例尺
mpt.AddScaleBar(ax, LOC = (0.2, 0.05), SCA = 0.12, FontSize = 6,
UnitPad = 0.2, BarWidth = 0.6)
cbar = fig.colorbar(cs,ax=ax,orientation='horizontal',
shrink=0.65,aspect=25,pad=.08)
cbar.ax.tick_params(labelsize=7.5,direction="in")
cbar.ax.tick_params(which="minor",direction="in")
#cbar.ax.xaxis.set_ticks_position('top')
cbar.set_label("Temperature (℃)",fontsize=9)
#cbar.ax.set_title("Sea Surface Temperature(m)",fontsize=9)
cbar.outline.set_linewidth(.4)
#plt.tight_layout()

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/85820f18d0.html
