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<=138)]
lat_range1=lat[(lat>=3)&(lat<=55)]
#南海九段线范围
lon_range2=lon[(lon>=104)&(lon<=125)]
lat_range2=lat[(lat>=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://www.toymoban.com/news/detail-736346.html
文章来源地址https://www.toymoban.com/news/detail-736346.html
到了这里,关于Python绘制中国地图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!