import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import h5py
# 读取经纬度和潜热.
filename = "2B.GPM.DPRGMI.2HCSHv3-1.20170503-S070958-E084232.018057.V05A.HDF5"
group = "Swath"
with h5py.File(filename, "r") as infile:
lat2d = np.array(infile[group+"/Latitude"])
lon2d = np.array(infile[group+"/Longitude"])
LH3d = np.array(infile[group+"/latentHeating"])
nscan = LH3d.shape[0]
nray = LH3d.shape[1]
nlayer = LH3d.shape[2]
# 选取所需的经纬度范围,还有想要画的ray.
ray = int(nray/2) + 20
lonmin = 105.0
lonmax = 120.0
latmin = 25.0
latmax = 40.0
# 根据官方文档设置对应的垂直高度.
layerSize = 0.25 # Units is km.
height = (np.arange(1, nlayer+1)-0.5)*layerSize
# 利用条件判断索引所需的潜热截面数据.
logi = np.logical_and.reduce((lat2d[:,ray] >= latmin, lat2d[:,ray] <= latmax, \
lon2d[:,ray] >= lonmin, lon2d[:,ray] <= lonmax))
lat = lat2d[logi,ray]
LH = LH3d[logi,ray,:]
print(LH.min(), LH.max())
# 定义一个能保证midpoint在colorbar正中间的normalize类.
class MidpointNormalize(mpl.colors.Normalize):
def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False):
self.midpoint = midpoint
mpl.colors.Normalize.__init__(self, vmin, vmax, clip)
def __call__(self, value, clip=None):
x, y = [self.vmin, self.midpoint, self.vmax], [0, 0.5, 1]
return np.ma.masked_array(np.interp(value, x, y))
# 做出潜热截面的填色图.
fig = plt.figure(dpi=300, figsize=(10,4))
ax = plt.subplot(111)
bounds = [-5.0, -2.0, -1.0, -0.1, 0.1, 1.0, 2.0, 5.0, 10.0, 20.0, 30.0]
norm = mpl.colors.BoundaryNorm(boundaries=bounds, ncolors=256)
im = ax.contourf(lat, height, LH.T, levels=bounds, cmap="seismic", extend="both", \
norm=MidpointNormalize(midpoint=0.0, vmin=min(bounds), vmax=max(bounds)))
ax.axhline(y=4.0, color="k", linestyle="--")
ax.set_xlabel("Latitude", fontsize=12)
ax.set_ylabel("Altitude (km)", fontsize=12)
ax.set_yticks(np.arange(25, step=5))
ax.set_title("CSH Latent Heat (K/hr)", fontsize=15)
cbar = fig.colorbar(im, ax=ax, ticks=bounds, orientation="horizontal", \
shrink=0.7, pad=0.2)
# plt.show()
fig.savefig("CSH_plot_py")