【Python气象绘图临摹】图像绘制(下):地理子图GeoAxes、xy轴设置、应用ncl色阶colormap、各标题、海岸线、添加文本、添加矩形框

文章目录

  • 前言
  • plt.fig.ax.三者绘制区别:
  • GeoAxes地图投影:绘图投影和数据投影
  • x轴、y轴设置:
  • 多个子图之间的间距调节:
  • 图上添加文本、矩形框:
  • python中ncl色阶colormap映射:
  • 代码


绘制结果图:
【Python气象绘图临摹】图像绘制(下):地理子图GeoAxes、xy轴设置、应用ncl色阶colormap、各标题、海岸线、添加文本、添加矩形框_第1张图片

前言

2022.9学习绘图
利用python进行气象绘图,本文为学习绘制期间记录笔记,分为上、下两部分:处理数据和图像绘制。图像绘制:区分plt.fig.ax.三者关系,设置地理子图GeoAxes地图投影、调节xy轴的具体设置、调节子图间距、添加文本、添加矩形框、应用ncl中的色阶colormap。

绘制用到(上)输出的var_all_sum_win.nc


函数中的具体参数可以去官网检索、或者百度。

plt.fig.ax.三者绘制区别:

在初学的时候,网上检索的绘图代码调用的方法大不一样,有时候用plt直接出图、有时候调用fig画布、有时候又用ax的方法,最后可能也实现了同一个绘图目的,让人摸不着头脑。
在此简单的区别一下三者关系:
·plt是matplotlib集成的绘图方法,简洁,可以直接一句话出图,适合不要求绘图质量只是看看大致分布的方法。所以精细的绘图指令不适用,在本文中一句都没有。
·fig指的是画布,直观理解是用查看器打开图片,背景那个白色的底板,每个子图都是绘制在fig上的。所以fig.的绘图指令适用于多个子图共用的元素设置,或者只有一个子图的情况。
·ax指axes,约定俗成把axes编程名字赋成ax。axes勉强翻译成绘图区域,每个子图都是一个axes区域,每个子图针对性的绘图设置必须用ax.进行精细设置。

GeoAxes地图投影:绘图投影和数据投影

创建气象上用的地理子图GeoAxes的基本方法就是,在创建Axes时指定projection参数!
要区分‘绘图投影‘和’数据投影‘:
·绘图的投影用于创建ax时,对应最后绘制出的地图投影。plt.subplots
·数据在处理时的投影,绘制的时候要进行转化,应用于set_extent() set_xticks() contourf()等。

设置绘图经纬度范围ax[i].set_extent(Region, crs=proj_data)时,一定要进行坐标系转换!!!!!

x轴、y轴设置:

x轴范围设置:
ax.set_xticks(np.arange(leftlon, rightlon+90., 90.), crs=proj)
给地图经纬度加上°E、°W等:
ax.xaxis.set_major_formatter(LongitudeFormatter(zero_direction_label=False))
x轴刻度线粗细、长短调节、字体大小:
tick_params(axis=‘x’, length=7, width=1.2, labelcolor=‘w’, labelsize=12)
x轴线和标签之间距离调节:
pad=5
ax.tick_params(axis=‘both’, length=7, pad=5, labelcolor=‘k’, width=1.2, labelsize=12)

多个子图之间的间距调节:

fig.subplots_adjust(hspace=-0.01) #纵向

图上添加文本、矩形框:

ax.text(10-180.,35,’a’,fontsize=13,fontweight=‘bold’,verticalalignment=‘center’,horizontalalignment=‘center’, bbox=dict(facecolor=‘w’, boxstyle=‘Square’, pad=textLTpad[i])) #pad默认0.3

boxa = patches.Rectangle((110,10),20,10 , linewidth=2, linestyle=‘-’, zorder=1, edgecolor=‘white’, facecolor=‘none’, transform=proj_data)
ax.add_patch(boxa)

python中ncl色阶colormap映射:

http://bbs.06climate.com/forum.php?mod=viewthread&tid=43521&extra=&page=1
下载cmaps安装即可


代码


import time
time_start = time.process_time()
import numpy as np
import xarray as xr
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
import cmaps
####################################################### 
##                读取方差数据
####################################################### 
f = xr.open_dataset('./var_all_sum_win.nc')
lon = f.lon
lat = f.lat
var_all = f['var_all']
var_sum = f['var_sum']
var_win = f['var_win']

####################################################### 
##                     PLOT
####################################################### 
proj      = ccrs.PlateCarree(central_longitude=180)
proj_data = ccrs.PlateCarree()                   # 数据的投影方式
leftlon, rightlon, lowerlat, upperlat = (-180, 180, -45, 45)
fig , ax  = plt.subplots(3,1,figsize=(8,8),subplot_kw={'projection':proj})

######## 调节绘图经纬度范围
for i in [0,1,2]:
    Region = [leftlon, rightlon, lowerlat, upperlat] #要绘制的范围 lon1,lon2,lat1,lat2
    ax[i].set_extent(Region, crs=proj_data) #经纬度范围,坐标参考系转换
for i in [0,1,2]:
    # x轴
    ax[i].set_xticks(np.arange(leftlon, rightlon+90., 90.), crs=proj) #纬度范围
    ax[i].xaxis.set_major_formatter(LongitudeFormatter(zero_direction_label=False)) #加°WE,0度不加EW
    ax[i].tick_params(axis='x', length=7, width=1.2, labelcolor='w', labelsize=12)
    # y轴
    ax[i].set_yticks(np.arange(lowerlat, upperlat+15., 15.), crs=proj) #经度范围
    ax[i].yaxis.set_major_formatter(LatitudeFormatter())
    ax[i].tick_params(axis='y', length=7, width=1.2, labelsize=12)
ax[2].tick_params(axis='both', length=7, pad=5, labelcolor='k', width=1.2,
                  labelsize=12)

# ######## 标题
ax[0].set_title('  Annual Mean',fontsize=14, y=1.05,loc='left', pad=0)
ax[1].set_title('  May-Oct.' , fontsize=14, y=1.05, loc='left', pad=0)
ax[2].set_title('  Nov.-Apr.', fontsize=14, y=1.05, loc='left', pad=0)

######## 添加地理信息
for i in [0,1,2]:
	ax[i].add_feature(cfeature.COASTLINE.with_scale('110m'),lw=0.5)# 添加海岸线

######## 子图间距
fig.subplots_adjust(hspace=-0.01, )

######## 大标题
fig.suptitle('Variance of 10-30d OLR',fontsize=16, y=0.91)

######## 加左上角abcd标识
textLT = ['a','b','c']
textLTpad = [0.25,0.25,0.3]
for i in [0,1,2]:
    ax[i].text(10-180.,35,textLT[i], fontsize=13, fontweight='bold',
               verticalalignment='center', horizontalalignment='center',
               bbox=dict(facecolor='w', boxstyle='Square', pad=textLTpad[i])) #pad默认0.3

######## 填色图hatches=['//\\',None]填充网格线显著性检验
lvl = np.arange(80.,680.+40.,40.)     #等值线间隔
qs1 = ax[0].contourf(lon,lat,var_all, zorder=0, levels=lvl, transform=proj_data,
                     cmap=cmaps.WhiteBlueGreenYellowRed, extend='both')
qs2 = ax[1].contourf(lon,lat,var_sum, zorder=0, levels=lvl, transform=proj_data,
                     cmap=cmaps.WhiteBlueGreenYellowRed, extend='both')
qs3 = ax[2].contourf(lon,lat,var_win, zorder=0, levels=lvl, transform=proj_data,
                     cmap=cmaps.WhiteBlueGreenYellowRed, extend='both')

####### 加白色矩形框 # (110-130E,10-20N) ; (80-95E,10-20N)
for i in [0,1,2]:
    boxa = patches.Rectangle((110,10),20,10 , linewidth=2, linestyle='-', zorder=1, 
                             edgecolor='white', facecolor='none', transform=proj_data)
    boxb = patches.Rectangle((80,10),15,10 , linewidth=2, linestyle='-', zorder=1, 
                             edgecolor='white', facecolor='none', transform=proj_data)
    ax[i].add_patch(boxa)
    ax[i].add_patch(boxb)

####### 色阶
colorbar = fig.add_axes([0.07, 0.07, 0.81, 0.015])
fig.colorbar(qs1, cax=colorbar, orientation='horizontal',
             format='%d', extendrect=True, drawedges=True)
fig.text(0.935,0.078,'W$^2$/m$^2$', fontsize=13, va='center', ha='center') 


plt.savefig('3.png',dpi=200)
plt.show()


time_end = time.process_time()
print('\nRunning time: %s Seconds'%(time_end-time_start))

你可能感兴趣的:(python气象处理和绘图,python,学习)