创建二维颜色映射,根据Levene Test p-value和KPSS Test p-value的值创建二维颜色映射,以便在主图中展示站点的稳定性分析。
绘制主图和子图,主图展示全球水文站点的稳定性分析,子图分别放大展示美国、欧洲、南美洲、非洲南部和澳大利亚的局部细节,并用颜色表示Mann-Kendall Test Statistic的值。
def
plot_stations_on_world_map(gdf, shapefile_path, stat_bins, pval_bins, color_matrix, stat_col, pval_col):
world = gpd.read_file(shapefile_path)
fig, ax_main = plt.subplots(figsize=(36, 28))
world.plot(ax=ax_main, color='lightgray', edgecolor='black')
for idx, row in gdf.iterrows():
stat_bin = np.digitize([row[stat_col]], stat_bins)[0] - 1
pval_bin = np.digitize([row[pval_col]], pval_bins)[0] - 1
color = color_matrix[pval_bin, stat_bin]
ax_main.scatter(row['geometry'].x, row['geometry'].y, color=color, s=50)
ax_main.grid(True, which='both', linestyle='--', linewidth=1)
ax_main.set_xticks(np.arange(-180, 181, 30))
ax_main.set_yticks(np.arange(-90, 91, 30))
ax_main.set_xticklabels([f'{x}°' for x in np.arange(-180, 181, 30)])
ax_main.set_yticklabels([f'{y}°' for y in np.arange(-90, 91, 30)])
ax_main.set_xlabel('Longitude')
ax_main.set_ylabel('Latitude')
insets = {
'USA': [-130, -60, 20, 55, [0.15, 0.71, 0.30, 0.30]],
'Europe': [-10, 30, 38, 65, [0.58, 0.74, 0.26, 0.26]],
'South America': [-80, -30, -55, -5, [0.1, 0.02, 0.28, 0.21]],
'Southern Africa': [20, 33, -33, -23, [0.40, 0.02, 0.22, 0.22]],
'Australia': [130, 155, -45, -20, [0.65, 0.02, 0.20, 0.24]]
}
filtered_gdf = filter_extreme_values(gdf, 'Mann-Kendall Test Statistic')
scaler = StandardScaler()
filtered_gdf['Mann-Kendall Test Statistic'] = scaler.fit_transform(filtered_gdf[['Mann-Kendall Test Statistic']])
max_abs_value = max(abs(filtered_gdf['Mann-Kendall Test Statistic'].min()), abs(filtered_gdf['Mann-Kendall Test Statistic'].max()))
norm = plt.Normalize(vmin=-max_abs_value, vmax=max_abs_value)
cmap = plt.get_cmap('coolwarm')
for region, (xmin, xmax, ymin, ymax, bbox) in insets.items():
ax_inset = fig.add_axes(bbox)
world.plot(ax=ax_inset, color='lightgray', edgecolor='black')
for idx, row in filtered_gdf.iterrows():
if xmin <= row['geometry'].x <= xmax and ymin <= row['geometry'].y <= ymax:
color = cmap(norm(row['Mann-Kendall Test Statistic']))
ax_inset.scatter(row['geometry'].x, row['geometry'].y, color=color, s=50)
ax_inset.set_xlim(xmin, xmax)
ax_inset.set_ylim(ymin, ymax)
ax_inset.grid(True, which='both', linestyle='--', linewidth=0.5)
ax_inset.set_xticks([])
ax_inset.set_yticks([])
cax_main = fig.add_axes([0.18, 0.40, 0.06, 0.08])
cax_main.imshow(color_matrix, origin='lower', aspect='auto', extent=[stat_bins.min(), stat_bins.max(), pval_bins.min(), pval_bins.max()])
cax_main.set_xticks([stat_bins[0], stat_bins[1], stat_bins[2]])
cax_main.set_yticks([pval_bins[0], pval_bins[1], pval_bins[2]])
cax_main.set_xticklabels([f'{stat_bins[0]:.2f}', '0.05', f'{stat_bins[2]:.2f}'])
cax_main.set_yticklabels([f'{pval_bins[0]:.2f}', '0.05', f'{pval_bins[2]:.2f}'])
cax_main.set_xlabel('Levene Test')
cax_main.set_ylabel('KPSS Test')
cax_main.set_title('Stationarity Analysis')
cax_inset = fig.add_axes([0.18, 0.35, 0.06, 0.02])
sm_inset = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm_inset.set_array([])
fig.colorbar(sm_inset, cax=cax_inset, orientation='horizontal', label='Mann-Kendall Test Statistic')
ax_pie1 = fig.add_axes([0.12, 0.25, 0.12, 0.12])
ax_pie2 = fig.add_axes([0.35, 0.25, 0.12, 0.12])
ax_pie3 = fig.add_axes([0.58, 0.25, 0.12, 0.12])
def plot_pie_chart(ax, sizes, labels, title, colors):
ax.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)
ax.axis('equal')
ax.set_title(title)
mk_stat_counts = [sum(gdf['Mann-Kendall Test Statistic'] > 0), sum(gdf['Mann-Kendall Test Statistic'] <= 0)]
plot_pie_chart(ax_pie1, mk_stat_counts, ['Increase', 'Decrease'], 'Mann-Kendall Test Statistic', ['#66c2a5', '#fc8d62'])
levene_pval_counts = [sum(gdf['Levene Test p-value'] > 0.05), sum(gdf['Levene Test p-value'] <= 0.05)]
plot_pie_chart(ax_pie2, levene_pval_counts, ['Not Significant', 'Significant'], 'Levene Test p-value', ['#8da0cb', '#e78ac3'])
kpss_pval_counts = [sum(gdf['KPSS Test p-value'] > 0.05), sum(gdf['KPSS Test p-value'] <= 0.05)]
plot_pie_chart(ax_pie3, kpss_pval_counts, ['Not Significant', 'Significant'], 'KPSS Test p-value', ['#a6d854', '#ffd92f'])
plt.show()