
代码绘制成果展示


该图展示了1980年至2022年间中国不同降水指数的城市化效应随时间的变化情况 ,横轴代表年份,纵轴代表八种不同的降水指数 。图中红色实线和蓝色实线分别代表城市和农村地区的滑动平均趋势,而浅色虚线则表示每年的原始数值 。灰色垂直虚线将时间轴划分为两个阶段:1980-1999年的基准期(蓝色阴影)和2000-2022年的近期(橙色阴影) ,两条曲线之间的阴影区域直观地反映了城市化效应(即城乡降水差异)的大小 。图中标注的“Delta”数值量化了这两个时期城市化效应的差异,正值意味着2000年后城市化效应加剧,负值则表示减弱 。从此图可以得出,自2000年以来,绝大多数降水指标的城市化效应显著增强,具体表现为城市地区的极端降水频率、强度和总量相对于农村显著上升 ,且这种城乡分异在最近二十年呈现加速扩大的趋势,表明城市化正在加剧城市区域的极端降水和洪涝风险 。








代码解释


第一部分

# =========================================================================================# ====================================== 1. 环境设置 =======================================# =========================================================================================import matplotlib.pyplot as pltimport numpy as npimport pandas as pdimport osfrom matplotlib.lines import Line2Dimport matplotlibimport matplotlib.colors as mcolors

第二部分

# =========================================================================================# ======================================2.颜色库=======================================# =========================================================================================COLOR_SCHEMES = {1: {'rural': '#003f5c', 'urban': '#d45087', 'pre': '#ADD8E6', 'post': '#FFE4B5', 'delta': '#ff7c43'},}SCHEME_ID = 40 #选择配色方案CURRENT_PALETTE = COLOR_SCHEMES.get(SCHEME_ID, COLOR_SCHEMES[1]) #获取配色

第三部分

# =========================================================================================# ======================================3.计算移动平均趋势的函数=======================================# =========================================================================================def calculate_rolling_trend(data_array, years, window=10):series = pd.Series(data_array, index=years) # 将输入的数据数组转换为Series对象rolling_data = series.rolling(window=window, #应用滚动窗口min_periods=1, # 设置最小观测值数量center=True).mean() #设置窗口居中并计算平均值return rolling_data # 返回计算后的移动平均数据

第四部分

反映城乡差距随时间变化的趋势变化量(差距是扩大了还是缩小了)。# =========================================================================================# ======================================4.计算Delta值的函数=======================================# =========================================================================================def calculate_did_delta(years, r_raw, u_raw):mask_pre = (years >= 1980) & (years <= 1999) #基准期mask_post = (years >= 2000) & (years <= 2022) #近期# 计算Deltadelta = ue_post - ue_pre# 格式化输出if abs(delta - round(delta)) < 0.001:return f"{int(round(delta))}"else:return f"{delta:.1f}"

第五部分

# =========================================================================================# ======================================3.子图绘制函数=======================================# =========================================================================================def draw_single_panel(ax, years, r_raw, r_roll, u_raw, u_roll, label, title, delta_val,is_xlabel=False):#原始数据折线ax.plot(years, #x轴r_raw, # Y轴color=COLOR_RURAL, #颜色linestyle='--', #线条样式alpha=0.3, #透明度linewidth=1) #线宽ax.plot(years, #x轴u_raw, #Y轴color=COLOR_URBAN, #颜色linestyle='--', #线条样式alpha=0.3, #透明度linewidth=1) #线宽

第六部分

mask_pre = years <= 2000 #筛选2000年及以前的年份mask_post = years >= 2000 # 筛选2000年及以后的年份# 曲线之间填充颜色ax.fill_between(years,#x轴r_roll, # 填充区域的下界u_roll, # 填充区域的上界where=mask_pre, # 仅在2000年及之前的区域填充interpolate=True, # 插值以获得平滑边缘color=FILL_COLOR_PRE, # 填充颜色alpha=0.5) #透明度

第七部分

#阈值线ax.axvline(x=2000, #xcolor='gray', # 颜色linestyle='--', # 样式linewidth=1.5, #线宽alpha=0.7) #透明度y_min, y_max = ax.get_ylim() # 获取当前Y轴的最小值和最大值# Delta文本ax.text(0.05, #x坐标0.9, #y坐标f'Delta: {delta_val}', # 文本内容transform=ax.transAxes, #指定坐标系fontsize=16, # 字体大小fontweight='bold', # 字体加粗color=DELTA_TEXT_COLOR, # 文本颜色bbox=dict(facecolor='#f0f0f0', # 文本框背景色edgecolor='none', # 文本框无边框alpha=0.7)) # 文本框透明度

第八部分

# 子图标题ax.set_title(label, #内容loc='left', # 左fontsize=18, # 字体大小fontweight='bold', # 加粗pad=10) # 标题与图表的间距# y轴标题ax.set_ylabel(title, #内容fontsize=16, #字体大小fontweight='bold') #加粗#设置刻度线ax.tick_params(axis='both', #x轴和y轴which='major', #主刻度length=4, #长度width=2, #宽度direction='out',#方向labelsize=14) #字体大小#设置刻度标注加粗for label in ax.get_xticklabels() + ax.get_yticklabels():label.set_fontweight('bold')if is_xlabel:ax.set_xlabel("Year", fontsize=14, fontweight='bold') # 设置X轴标题

第九部分

# =========================================================================================# ======================================4.主绘图函数=======================================# =========================================================================================def create_and_save_charts(df, years):# 动态获取变量列表,并去除后缀作为变量名variable_names = [col.replace('_Rural', '') for col in df.columns if col.endswith('_Rural')]# 动态计算所需的行数和列数num_vars = len(variable_names)# 调整子图间的间距plt.subplots_adjust(wspace=0.3,hspace=0.3)axes_flat = axes.flatten() # 将二维的axes数组展平为一维,便于迭代

第十部分

# 遍历变量列表for i, title in enumerate(variable_names):# 生成子图标签label = f"{chr(97 + i)}."r_raw = df[f'{title}_Rural'].values # 根据标题构建列名,获取农村原始数据值u_raw = df[f'{title}_Urban'].values # 根据标题构建列名,获取城市原始数据值#绘制子图draw_single_panel(ax_comb, # 面板years, # 年份数据r_raw, # 农村原始数据r_roll, # 农村平滑数据u_raw, # 城市原始数据u_roll, # 城市平滑数据label, # 子图标签title, # 变量标题delta, #Delta值is_xlabel=show_xlabel) # 是否显示X轴标题

第十一部分

fig_single, ax_single = plt.subplots(figsize=(5, 4), dpi=150) # 创建一个独立画布用于保存单张子图draw_single_panel(ax_single, years,r_raw,r_roll,u_raw,u_roll,label,title,delta,is_xlabel=True)plt.tight_layout() # 自动调整布局# 保存fig_single.savefig(fr"subplot_{title}.png", dpi=300, bbox_inches='tight')fig_single.savefig(fr"subplot_{title}.pdf", bbox_inches='tight')plt.close(fig_single) # 关闭

第十二部分

# 隐藏多余的空白子图for j in range(i + 1, len(axes_flat)):axes_flat[j].axis('off')# 自定义图例句柄列表custom_lines = [Line2D([0],[0], # 初始坐标color=COLOR_RURAL, # 颜色lw=2), #线宽Line2D([0], [0], color=COLOR_RURAL, lw=1.5, linestyle='--'),Line2D([0], [0], color=COLOR_URBAN, lw=2),Line2D([0], [0], color=COLOR_URBAN, lw=1.5, linestyle='--')]plt.subplots_adjust(bottom=0.15) # 调整底部边距#保存fig_combined.savefig(fr"{SCHEME_ID}.png", dpi=300, bbox_inches='tight')fig_combined.savefig(fr"{SCHEME_ID}.pdf", bbox_inches='tight')

第十三部分

# =========================================================================================# ======================================5.运行入口=======================================# =========================================================================================if __name__ == "__main__":DATA_FILE_PATH = r"data.xlsx" #数据文件路径df = pd.read_excel(DATA_FILE_PATH, index_col=0) # 读取数据years = df.index.values # 获取年份索引值# 执行绘图函数create_and_save_charts(df, years)

如何应用到你自己的数据

1.设置颜色方案:
SCHEME_ID = 40 #选择配色方案2.设置分期数据:
mask_pre = (years >= 1980) & (years <= 1999) #基准期mask_post = (years >= 2000) & (years <= 2022) #近期
3.设置子图的保存地址:
fig_single.savefig(fr"subplot_{title}.png", dpi=300, bbox_inches='tight')fig_single.savefig(fr"subplot_{title}.pdf", bbox_inches='tight')
4.设置组合图的保存地址:
fig_combined.savefig(fr"{SCHEME_ID}.png", dpi=300, bbox_inches='tight')fig_combined.savefig(fr"{SCHEME_ID}.pdf", bbox_inches='tight')
5.设置原始数据的保存路径:
DATA_FILE_PATH = r"data.xlsx" 
推荐


获取方式
