上两期文章见:
Python Cartopy地图投影【1】
第一期文章内容纲要:
step1: 开始地图投影
step2: GeoAxes 的常用方法
2.1 add_feature:添加海岸线、河流、湖泊等地理特征
2.2 gridlines:添加网格线以及相应标签等
Python Cartopy地图投影【2】
第二期文章内容纲要:
2.3 set_extent:设置地理边界
2.4 set_boundary:裁剪子图形状
step3: 三种常见地图投影与实用技巧
3.1 等距网格投影 PlateCarree
3.2 兰伯特投影 LambertConformal
3.3 NorthPolarStereo (北)极地投影
什么叫 Cartopy 与 matplotlib 的结合呢?就是用 matplotli 来画图、用 cartopy 来创建地图投影以及添加相应的地理特征要素。
import xarray as xr # 用于读取数据
import matplotlib.pyplot as plt # 用于绘图基础
import cartopy.crs as ccrs # 用于调用投影
import cartopy.feature as cfeature # 用于调用地理特征要素
f = xr.open_dataset('air.mon.mean.nc') # 读取数据
t = f['air'].loc[:, 500, :, :][0] # 取出第一个时刻的500hPa的温度场
lat = f['lat'] # 取出经度
lon = f['lon'] # 取出纬度
plt.figure(figsize=(5, 5)) # 创建figure对象
# ax1为Axes
ax1 = plt.subplot(1, 2, 1) # 创建1行2列的第一个axes
c1 = ax1.contour(lon, lat, t) # 绘制温度等值线
ax1.set_title('Axes') # 标题
# ax2为GeoAxes
ax2 = plt.subplot(1, 2, 2, projection=ccrs.PlateCarree()) # 创建1行2列的第二个GeoAxes
c2 = ax2.contour(lon, lat, t, transform=ccrs.PlateCarree()) # 绘制等值线
ax2.add_feature(cfeature.COASTLINE) # 添加海岸线
ax2.set_title('GeoAxes') # 添加标题
plt.show(); # 展示图形
我们来看看在极坐标投影上绘图时,是否添加 transform 参数会分别得到怎样的结果?
# 极坐标投影是否添加transform参数的效果对比
import matplotlib.pyplot as plt
import numpy as np # 用于生成圆形的参数
import cartopy.crs as ccrs
import cartopy.feature as cfeature # 用于调用地理特征要素
import matplotlib.path as mpath # 用于生成极坐标的圆形边界
f = xr.open_dataset('/home/mw/input/moyu1828/air.mon.mean.nc') # 读取数据
t = f['air'].loc[:, 500, :, :][0] # 取出第一个时刻的500hPa的温度场
lat = f['lat'] # 读取纬度
lon = f['lon'] # 读取经度
theta = np.linspace(0, 2*np.pi, 100) # 生成极坐标圆形方程的theta参数
center, radius = [0.5, 0.5], 0.5 # 圆心和半径
verts = np.vstack([np.sin(theta), np.cos(theta)]).T
circle = mpath.Path(verts * radius + center) # 生成圆形边界
fig = plt.figure(figsize=[5, 5]) # 生成figure对象
# 第一个子图,绘图时设置transform参数
# 生成1行2列第一个的北极极地投影子图
ax1 = fig.add_subplot(1, 2, 1, projection=ccrs.NorthPolarStereo())
ax1.set_extent([-180, 180, 30, 90], ccrs.PlateCarree()) # 设置投影范围为30°-90°N半球
ax1.gridlines() # 绘制网格线
ax1.add_feature(cfeature.COASTLINE) # 添加海岸线
ax1.set_boundary(circle, transform=ax1.transAxes) # 设置子图边界
# 绘制等值线,指定transform=ccrs.PlateCarree()
ax1.contour(lon, lat, t, transform=ccrs.PlateCarree())
# 第二个子图,绘图时不设置transform参数
# 生成1行2列第二个的北极极地投影子图
ax2 = fig.add_subplot(1, 2, 2, projection=ccrs.NorthPolarStereo())
ax2.set_extent([-180, 180, 30, 90], ccrs.PlateCarree()) # 设置投影范围为30°-90°N半球
ax2.gridlines() # 绘制网格线
ax2.add_feature(cfeature.COASTLINE) # 添加海岸线
ax2.set_boundary(circle, transform=ax2.transAxes) # 设置子图边界
ax2.contour(lon, lat, t) # 绘制等值线,没有指定transform=ccrs.PlateCarree()
plt.show()