最近终于把之前的工作收尾了,就等老外再看一遍了。开始一个新的项目,从复现老外的文章开始。
主要包括:
第一个较为简单,通过设置不同的bins,统计每个bins中降水的分布即可。
BIN_EDGES_MM_DAY = (
0.0, 0.1, 1, 2, 3, 4, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50,
60, 70, 80, 90, 100, 125, 150, 175, 200, 225, 250, 275, 300,
)
pdf_density, bin_edges = np.histogram(ds, bins=BIN_EDGES_MM_DAY, density=True)
plt.plot(BIN_EDGES_MM_DAY[:-1], pdf_density, drawstyle='steps-post')
plt.xscale('log')
plt.yscale('log')
plt.xlabel('Precipitation (mm/day)')
plt.ylabel('Probability Density')
plt.title('Precipitation Probability Density Function')
plt.grid(True, which='both', linestyle='--', linewidth=0.5)
plt.show()

本质上是为了,基于之前分的不同降水区间,去计算每个降水区间贡献了多少总降水:降水率落在 τ 到 τ+δτ 这一区间内时,对全年热带平均降水的贡献,这可以回答以下问题:
上述公式的分子A(lon,lat,time)类似一个掩膜的作用,如果某个格点在某一天的降水数值满足τ 到 τ+δτ,例如[0,1],那么将这个格点mask为1,否则为0,目的就是为了只保留该降水区间内降水格点,其他都置为0.这是为了方便统计这一降水区间[0,1]对热带平均降水的贡献。
在此基础上,需要进一步计算每个降水区间实际占据了多少面积,所以这里需要计算实际的经纬度网格的格点之间的球面积,考虑到lat不同范围进行cos加权。
defcal_area(dset, x_step=None, y_step=None):
"""Calculate the horizontal area of each lat-lon grid box.
dx=RcosϕΔλ
dy=RΔϕ
area=dx*dy=R^2cosϕΔλΔϕ
delta x = x_step (degree) x pi/180 x Earth radius
delta y = y_step (degree) x pi/180 x Earth radius
"""
if x_step isNone:
x_step = float(np.abs(np.diff(dset.lon.values)).mean())
if y_step isNone:
y_step = float(np.abs(np.diff(dset.lat.values)).mean())
earthr = 6.371e6
lon2d, lat2d = np.meshgrid(dset.lon.values, dset.lat.values)
area = xr.DataArray(
data=(x_step / 180 * np.pi) * earthr * np.cos(np.deg2rad(lat2d)) * (y_step / 180 * np.pi) * earthr,
dims=["lat", "lon"],
coords={"lat": dset.lat.values, "lon": dset.lon.values},
)
return area
area = cal_area(ds)
precip_values = ds.values.reshape(-1) # flattern to 1D array
area_values = np.broadcast_to(area.values, ds.shape).reshape(-1) # flattern
area_total, _ = np.histogram(precip_values, bins=BIN_EDGES_MM_DAY, weights=area_values)
再次调用histogram函数,将面积权重加进去,得到每个降水区间占了多少面积,预期统计结果大概就是:

进一步的,但是我们需要思考的是,小雨占据了最大的空间面积,他对于总降水的贡献就是最重要的吗?
precip_total, _ = np.histogram(
precip_values,
bins= BIN_EDGES_MM_DAY,
weights=precip_values * area_values,
)
plt.plot(BIN_EDGES_MM_DAY[:-1], precip_total, drawstyle='steps-post')
plt.xscale('log')
plt.xlabel('Precipitation (mm/day)')
plt.ylabel('Probability Density')
plt.title('Precipitation Probability Density Function')
plt.grid(True, which='both', linestyle='--', linewidth=0.5)
plt.show()

进一步计算,第 i 个降水区间对区域平均降水的贡献。
total_area = area_values.sum() # 计算总面积
bin_mean_contribution = precip_total / total_area
plt.plot(BIN_EDGES_MM_DAY[:-1], bin_mean_contribution, drawstyle='steps-post')
plt.xscale('log')
plt.xlabel('Precipitation (mm/day)')
plt.ylabel('Contribution to Total Precipitation')
plt.title('Contribution of Each Precipitation Bin to Total Precipitation')
plt.grid(True, which='both', linestyle='--', linewidth=0.5)
plt.show()

进一步计算:从小雨到大雨逐步累加时,各降水强度对总降水的累计贡献。cumulative_precip = np.cumsum(bin_mean_contribution)
plot_df = distribution_df.loc[distribution_df['bin_center_mm_day'] > 0].copy()
pdf_df = plot_df.loc[plot_df['pdf_density'] > 0].copy()
fig = plt.figure(figsize=(12, 6))
gs = fig.add_gridspec(
nrows=2,
ncols=2,
width_ratios=(1.45, 1.0),
height_ratios=(1.0, 1.0),
wspace=0.28,
hspace=0.32,
)
ax_pdf = fig.add_subplot(gs[:, 0])
ax_bin = fig.add_subplot(gs[0, 1])
ax_cum = fig.add_subplot(gs[1, 1])
line_kwargs = dict(
color='#1f4e79',
lw=2.2,
marker='o',
ms=3.8,
markerfacecolor='white',
markeredgewidth=0.9,
solid_capstyle='round',
)
ax_pdf.plot(pdf_df['bin_center_mm_day'], pdf_df['pdf_density'], **line_kwargs)
ax_bin.plot(plot_df['bin_center_mm_day'], plot_df['bin_mean_contribution_mm_day'], **line_kwargs)
bar_left = plot_df['bin_left_mm_day'].to_numpy(copy=True)
bar_width = (plot_df['bin_right_mm_day'] - plot_df['bin_left_mm_day']).to_numpy()
# The first bin starts at 0 mm/day, which cannot be shown directly on a log x-axis.
if bar_left[0] <= 0:
bar_left[0] = plot_df['bin_center_mm_day'].iloc[0] * 0.5
bar_width[0] = plot_df['bin_right_mm_day'].iloc[0] - bar_left[0]
ax_bin.bar(
bar_left,
plot_df['bin_mean_contribution_mm_day'],
width=bar_width,
align='edge',
facecolor='none',
edgecolor='#1f4e79',
linewidth=0.8,
alpha=0.9,
zorder=1,
)
ax_cum.plot(plot_df['bin_center_mm_day'], plot_df['cumulative_fraction'], **line_kwargs)
x_min = float(plot_df['bin_center_mm_day'].iloc[0])
x_max = float(plot_df['bin_center_mm_day'].iloc[-1])
for ax in (ax_pdf, ax_bin, ax_cum):
ax.set_xscale('log')
ax.set_xlim(x_min * 0.9, x_max * 1.05)
ax.grid(True, which='major', color='#d0d0d0', lw=0.6, alpha=0.8)
ax.grid(True, which='minor', color='#ececec', lw=0.4, alpha=0.9)
ax.tick_params(which='both', direction='in', top=False, right=False)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.xaxis.set_major_locator(LogLocator(base=10.0))
ax.xaxis.set_minor_locator(LogLocator(base=10.0, subs=np.arange(2, 10) * 0.1))
ax.xaxis.set_minor_formatter(NullFormatter())
ax_pdf.set_yscale('log')
ax_pdf.set_xlabel('Precipitation rate (mm day$^{-1}$)')
ax_pdf.set_ylabel('PDF density')
ax_pdf.text(0.02, 0.98, '(a)', transform=ax_pdf.transAxes, ha='left', va='top', fontweight='bold')
ax_pdf.set_title('PDF of precipitation rates', loc='left', pad=10)
# This is the mean precipitation contributed by each bin to the whole sample.
ax_bin.set_ylabel(r'$\overline{[P]}_{\tau}^{\tau + \delta\tau}$ (mm day$^{-1}$)')
ax_bin.text(0.02, 0.98, '(b)', transform=ax_bin.transAxes, ha='left', va='top', fontweight='bold')
ax_bin.set_title('Mean precipitation contributed by each bin', loc='left', pad=10)
ax_cum.set_xlabel('Precipitation rate (mm day$^{-1}$)')
ax_cum.set_ylabel(r'$\frac{\overline{[P]}_{0}^{\tau}}{\overline{[P]}_{0}^{\infty}}$')
ax_cum.text(0.02, 0.98, '(c)', transform=ax_cum.transAxes, ha='left', va='top', fontweight='bold')
ax_cum.set_title('Cumulative contribution', loc='left', pad=10)
ax_cum.set_ylim(0.0, 1.02)
ax_cum.axhline(0.5, color='#b7b7b7', lw=0.8, ls='--', zorder=0)
ax_cum.axhline(0.9, color='#d0d0d0', lw=0.8, ls=':', zorder=0)
plt.show()

下面是原文的结果:

为了分析热带降水的日常变化(以下也称为热带降水变化),我们遵循 Atlas 等人(1990)引入的框架。 我们首先根据**个别日降水率计算年平均降水量和热带平均降水量**:
左侧的术语表示从到的年平均热带降水量的降水率,例如从(0.1 mm/day 到1 mm/day)
使用所有降水率得出年热带平均降水量。
表示热带求和,分别沿着经度和纬度
这里定义热带纬度范围是30S-30N,P 为格点降水率, 是一个掩膜,对于任何一个时刻某一个空间的网格点降水,进行判断,
如果满足,
那么取1,否则取0举个例子,如果一个时刻上某一个空间网格点到降水大于0.1mm/day,小于1mm/day,就把这个格点取为1,否则为0.
★Segura, H., and C. Hohenegger, 2024: How Do the Tropics Precipitate? Daily Variations in Precipitation and Cloud Distribution. Journal of the Meteorological Society of Japan, 102, 525–537, https://doi.org/10.2151/jmsj.2024-028.