🌊 用 Python 揭示海洋的脉动:全球变量趋势图 + 纬度聚合统计实战
今天,我们就用 Python 带你复现一篇高影响力论文中的经典组合图——全球海洋变量均值趋势图搭配纬度带聚合统计图,一横一纵,洞察海洋变化的宏观格局与区域特征。
📊 图中展示的是某海洋变量(如海表温度、盐度或溶解氧)在全球范围内的长期变化趋势,并通过纬度方向的统计聚合,揭示其随纬度分布的系统性规律。
无论你是在撰写 SCI 论文、准备学术报告,还是希望提升科研绘图的专业度,这篇教程都将为你提供可直接运行的代码模板与顶刊级别的设计逻辑。
#Python #数据分析 #海洋学 #气候变化 #科学可视化
完整可复制代码全球海洋变量均值趋势图_纬度统计图.zip、可复现图、出版级排版原则。
点击关注上方“翔的学术日记”,选择加"星标"置顶重磅干货,第一时间送达
复现结果
01 复现结果图

02 全文内容速览
1. 复现分析
2. 代码讲解

def plot_mean_tr_ocean_var(var_mean,var_trend,var_name='Salinity',units='psu',trend_units='psu decade$^{-1}$',cmap={'mean': 'viridis', 'trend': 'RdBu_r'},mean_norm=mpl.colors.Normalize(vmin=30, vmax=37),trend_range=(-0.05, 0.05),save_path=None):fig = plt.figure(figsize=(30, 15), dpi=600)fig, axs = plt.subplots(nrows=4, ncols=1,subplot_kw={'projection': ccrs.Robinson(central_longitude=180)})ccrs_land = feature.NaturalEarthFeature('physical', 'land', '50m',edgecolor='darkgrey',facecolor='darkgrey',linewidth=0.2)# ================= Mean map =================im_mean = var_mean.plot(ax=axs[0],transform=ccrs.PlateCarree(),add_colorbar=False,cmap=cmap['mean'],norm=mean_norm,rasterized=True)axs[0].set_extent([0.1, 359.99, -85, 85], crs=ccrs.PlateCarree())axs[0].add_feature(ccrs_land)axs[0].set_title(f"a {var_name}",loc='left', fontsize=15, fontweight='bold', fontname='Arial')# colorbar (mean)cax = fig.add_axes([0.41, 0.7226, 0.005, 0.15])cbar = fig.colorbar(im_mean, cax=cax, extend='both')cbar.set_label(units, fontsize=13, fontname='Arial', labelpad=-55)cbar.ax.tick_params(labelsize=12)cbar.ax.yaxis.tick_left()# ================= Trend map =================ax_tr = plt.axes([0.4183, 0.49, 0.19, 0.168], projection=ccrs.Robinson(central_longitude=180))im_tr = var_trend.plot(ax=ax_tr, transform = ccrs.PlateCarree(), add_colorbar=False, cmap=cmap['trend'], vmin=trend_range[0], vmax=trend_range[1], rasterized=True)ax_tr.set_extent([0.1, 359.99, -85, 85], crs=ccrs.PlateCarree())ax_tr.add_feature(ccrs_land)ax_tr.set_title(f"d {var_name} trend", loc='left', fontsize=15, fontweight='bold', fontname='Arial')cax = fig.add_axes([0.41, 0.50, 0.005, 0.15])cbar = fig.colorbar(im_tr, cax=cax, extend='both')cbar.set_label(trend_units, fontsize=13, fontname='Arial', labelpad=-65)cbar.ax.tick_params(labelsize=12)cbar.ax.yaxis.tick_left()# ================= Zonal mean =================ax_zm1 = plt.axes([0.615, 0.7126, 0.05, 0.167])zm = var_mean.mean(axis=1)y = var_mean.latax_zm1.fill_betweenx(y, 0, zm, color=mpl.colormaps[cmap['mean']](0.6))ax_zm1.set_yticks(range(-80,81,20))ax_zm1.set_yticklabels(['80$\u00b0$S','60$\u00b0$S','40$\u00b0$S','20$\u00b0$S','0$\u00b0$','20$\u00b0$N','40$\u00b0$N','60$\u00b0$N','80$\u00b0$N'],fontname = 'Arial', fontsize = 12)ax_zm1.set_title("b Salinity", loc='left', fontsize=15, fontweight='bold')ax_zm1.set_xlabel(units)ax_zm1.axvline(0, color='k')ax_zm2 = plt.axes([0.615, 0.49, 0.05, 0.167])zm_tr = var_trend.mean(axis=1)y = var_trend.latcmap_tr = mpl.colormaps[cmap['trend']]pos = np.ma.masked_where(zm_tr < 0, zm_tr)ax_zm2.fill_betweenx(y, 0, pos, color=cmap_tr(0.85), linewidth=1,alpha=1)neg = np.ma.masked_where(zm_tr > 0, zm_tr)ax_zm2.fill_betweenx(y, 0, neg, color=cmap_tr(0.15), linewidth=1, alpha=1)ax_zm2.set_yticks(range(-80,81,20))ax_zm2.set_yticklabels(['80$\u00b0$S','60$\u00b0$S','40$\u00b0$S','20$\u00b0$S','0$\u00b0$','20$\u00b0$N','40$\u00b0$N','60$\u00b0$N','80$\u00b0$N'],fontname = 'Arial', fontsize = 12)ax_zm2.set_title(f"e {var_name} trend", loc='left', fontsize=15, fontweight='bold', fontname='Arial')ax_zm2.set_xlabel(trend_units, fontsize=13, fontname='Arial')ax_zm2.axvline(0, color='k', linewidth=0.8)for i in [1, 2, 3]:fig.delaxes(axs[i])if save_path:plt.savefig(save_path, dpi=600, bbox_inches='tight')plt.show()