当前位置:首页>python>期刊图片复现|Python绘制双向子弹图+百分比环图组合图

期刊图片复现|Python绘制双向子弹图+百分比环图组合图

  • 2026-10-21 13:27:10
期刊图片复现|Python绘制双向子弹图+百分比环图组合图

代码绘制成果展示

论文:Global subsidence of river deltas
论文原图
这张图展示了全球30个主要河口三角洲的地面沉降速率与地心海平面上升速率的定量对比及分布特征 。图表主体以中间纵列对齐的三角洲名称为轴心,分为左右两个坐标系。
左侧横坐标轴表示沉降速率,单位为cm yr⁻¹;通过叠加的条形图展示三种沉降指标:深栗色竖线代表平均沉降率,浅黄色条块代表第95百分位沉降率,而延伸最长的橙色条块代表最大沉降率 。
右侧横坐标轴表示海平面上升(SLR)速率,单位同样为厘米/年;该区域通过条形图展示不同时期的SLR速率:深蓝色代表当前速率,浅青色代表SSP2-4.5情景下的2050年预测值,天蓝色代表同情景下的2100年预测值 。图中包含两个关键的黑色箭头指示:右侧有一个水平箭头指向“珠江”三角洲所在的行,对其进行特指;左侧底部有一个垂直向上的箭头,指向一条贯穿左侧图表的黑色垂直虚线,该虚线标示了所有三角洲中2100年预估的最大海平面上升率,作为一个基准,凸显出绝大多数三角洲的沉降速率远超气候驱动的海平面上升速率 。
左下角内嵌了一个同心环形图,展示了沉降现象在各大洲的分布比例:外环代表最大沉降率的分布,内环代表第95百分位沉降率的分布;图中使用不同颜色区分大洲,并标注了具体数值。 
注意,此为个人理解,可能存在错误,具体内容还请阅读原文进行理解。
仿图
多种配色

代码解释

第一部分

库的导入以及字体设置
# =========================================================================================# ====================================== 1. 环境设置 =======================================# =========================================================================================import matplotlib.pyplot as pltfrom matplotlib.patches import Patch, FancyBboxPatchimport pandas as pdimport numpy as npimport matplotlibfrom matplotlib.lines import Line2Dplt.rcParams['font.family'] = 'serif'plt.rcParams['font.serif'] = ['Times New Roman']matplotlib.rcParams['pdf.fonttype'] = 42matplotlib.rcParams['ps.fonttype'] = 42

第二部分

颜色库设置以及配色方案的选择
# =========================================================================================# ======================================2.颜色库=======================================# =========================================================================================COLOR_SCHEMES = {    1: {        'sub_max': '#FFA500', 'sub_95': '#FFFACD', 'sub_mean': '#800000',        'slr_2100': '#4169E1', 'slr_2050': '#87CEEB', 'slr_curr': '#000080',        'pie': ['#EBCBCB', '#FFFAFA', '#D49A9A', '#C67E7E', '#B06666']    },}SCHEME_ID = 40  #选择配色方案colors = COLOR_SCHEMES.get(SCHEME_ID, COLOR_SCHEMES[1])  # 获取颜色方案

第三部分

内嵌饼图绘制函数,用于在主图的特定位置绘制一个带背景的双层环形图,展示不同区域的统计分布。在绝对位置创建一个子图。 利用 FancyBboxPatch 绘制一个圆角矩形背景,增加图表美观度。绘制双层饼图。使用 ax.annotate 添加箭头指引,说明外圈和内圈的含义。最后手动生成自定义图例,以确保图例顺序和颜色对应正确。

# =========================================================================================# ======================================3.内嵌饼图绘制函数=======================================# =========================================================================================def draw_styled_pie_chart(fig, box_position, df_pie):    ax = fig.add_axes(box_position)  # 在图形的指定位置添加一个新的坐标轴    ax.axis('off')  # 不显示边框和刻度    bg_color = '#EEEEEE'  # 背景颜色    border_color = '#A0A0A0'  # 边框颜色    # 创建背景    fancy_box = FancyBboxPatch(        (0, 0),  # 左下角坐标        1,  # 宽        1,  #高度        boxstyle="round,"# 样式                 "pad=-0.005,"# 内边距                 "rounding_size=0.03",  #圆角大小        facecolor=bg_color,  # 填充颜色        edgecolor=border_color,  # 边框颜色        linewidth=0.8,  # 线宽        transform=ax.transAxes,  # 坐标系        zorder=0,  # 设图层顺序,        mutation_scale=1  # 设置变形比例    )    # 注释文本    ax.annotate('Maximum',  # 文本                xy=(-0.7, 0.55),  # 箭头指向的坐标点                xytext=(-0.95, 0.8),  # 文本显示的坐标点                # 箭头属性                arrowprops=dict(arrowstyle="-",  # 样式                                color='black',  # 颜色                                lw=0.8),  # 线宽                fontsize=14,  # 字体大小                ha='center')  # 水平居中    leg = ax.legend(handles=reordered_handles,#指定要显示的图例句柄列表                    loc='lower center',  # 位置                    bbox_to_anchor=(0.5, -0.02),  #位置                    ncol=3,  # 列                    frameon=False,  # 不显示图例边框                    fontsize=14,  # 字体大小                    handlelength=1.2,  # 图例句柄长度                    handleheight=0.7,  # 图例句柄高度                    columnspacing=0.8,  # 列间距                    handletextpad=0.4)  # 图例形状和文本的间距    ax.set_aspect('equal')  #设置坐标轴纵横比

第四部分

图例绘制函数,手动构建图例项,通过Patch 对象手动定义每个色块的颜色和标签。使用 Line2D 手动绘制了一个方括号形状的线条。

# =========================================================================================# ======================================4.组合图例绘制函数=======================================# =========================================================================================def draw_combined_legend(fig, box_position):    ax = fig.add_axes(box_position)  # 添加坐标轴    ax.axis('off')  # 关闭坐标轴显示    bg_color = '#EEEEEE'  # 背景色    border_color = '#A0A0A0'  # 边框色    # 创建背景矩形    fancy_box = FancyBboxPatch(        (0, 0), # 位置        1, # 宽        1,  # 高        boxstyle="round,pad=-0.005,rounding_size=0.03",  # 样式        facecolor=bg_color,  # 填充色        edgecolor=border_color,  # 边框色        linewidth=0.8,  # 线宽        transform=ax.transAxes,  # 坐标系        zorder=0,  # 图层顺序        mutation_scale=1  # 变形比例    )    ax.add_patch(fancy_box)  # 添加背景    # 创建图例    leg2 = ax.legend(handles=handles_slr,  #指定要显示的图例句柄列表                     title='gSLR rates',  # 标题                     loc='upper left',  # 位置                     bbox_to_anchor=(0.02, 0.58),  # 位置                     frameon=False,  # 无边框                     fontsize=14,  # 字体大小                     title_fontsize=14,  # 标题大小                     labelspacing=0.2,  # 标签间距                     borderaxespad=0.5,  # 边界间距                     handletextpad=0.4)  # 图例形状和文本的间距    ax.add_line(line)  # 添加线条    # 添加文本    ax.text(line_x + 0.08,  #x位置            (line_y_top + line_y_bottom) / 2,  # y位置            'SSP2-4.5',  # 文本内容            va='center',  # 垂直居中            ha='left',  # 水平左对齐            fontsize=14,  # 字体大小            transform=ax.transAxes)  # 坐标系变换

第五部分

双向子弹图+百分比环图组合图绘制函数:创建画布与布局初始化

# =========================================================================================# ======================================5.双向子弹图+百分比环图组合图绘制函数=======================================# =========================================================================================def plot_delta_chart(df, df_pie):    fig = plt.figure(figsize=(15, 14))  # 创建图形    # 添加网格布局    gs = fig.add_gridspec(1,  # 行                          3,  # 列                          width_ratios=[6, 1.2, 3],  # 列宽比例                          wspace=0.05)  # 列间距    ax_sub = fig.add_subplot(gs[0])  # 左侧子图    ax_mid = fig.add_subplot(gs[1])  # 中间子图    ax_slr = fig.add_subplot(gs[2])  # 右侧子图

第六部分

双向子弹图+百分比环图组合图绘制函数:背景斑马线与条形图绘制

    y_pos = np.arange(len(df))  # 生成y轴位置数组    h_large = 0.8  # 大柱子的高度    h_med = 0.5  # 中柱子的高度    h_small = 0.25  # 小柱子的高度    for i in range(len(df)):  # 遍历每一行数据    ax_sub.barh(y_pos,  #y                df['Sub_Max'],  # 数据                height=h_large,  # 高度                color=colors['sub_max'],  # 颜色                label='Maximum',  # 标签                zorder=2)    ax_sub.barh(y_pos, df['Sub_95'], height=h_med, color=colors['sub_95'], label='95th percentile', zorder=3)  # 绘制95分位数条形图    ax_sub.barh(y_pos, df['Sub_Mean'], height=h_small, color=colors['sub_mean'], label='Mean', zorder=4)  # 绘制均值条形图

第七部分

双向子弹图+百分比环图组合图绘制函数:左侧坐标轴设置

    ax_sub.set_xlim(0, 18)  # x轴范围    ax_sub.invert_xaxis()  # 反转x轴方向    ax_sub.set_ylim(-0.8, len(df) - 0.2)  # y轴范围    # 网格线    ax_sub.grid(axis='x',  #x轴                linestyle='-',  # 实线                alpha=0.5,  # 透明度                color='gray')  # 灰色    # 设置标题    ax_sub.set_title('Subsidence rate ($cm \cdot yr^{-1}$)',  #文本内容                     pad=15,  # 标题距离                     fontsize=16)  # 字体大小    # 绘制垂直辅助线    ax_sub.axvline(0.5,  # x坐标                   color='black',  # 黑色                   linewidth=1,  # 线宽                   linestyle='--',  # 虚线                   zorder=200)

第八部分

双向子弹图+百分比环图组合图绘制函数:右侧条形图与设置

    # 绘制2100    ax_slr.barh(y_pos,  #y坐标                df['SLR_2100'],  # 数据                height=h_large,  # 高度                color=colors['slr_2100'],  # 颜色                label='2100',  # 标签                zorder=2)    ax_slr.barh(y_pos, df['SLR_2050'], height=h_med, color=colors['slr_2050'], label='2050', zorder=3)  # 绘制2050    ax_slr.barh(y_pos, df['SLR_Current'], height=h_small, color=colors['slr_curr'], label='Current', zorder=4)  # 绘制当前    ax_slr.set_xlim(0, 1.2)  # x轴范围    ax_slr.set_ylim(-0.8, len(df) - 0.2)  # y轴范围    ax_slr.tick_params(left=False,  # 隐藏左侧刻度线                       labelleft=False,  # 隐藏左侧标签                       bottom=False,  # 隐藏底部刻度                       labeltop=True,  # 显示顶部标签                       top=False,  # 隐藏顶部刻度线                       labelsize=16)  # 标签大小    # 设置标题    ax_slr.set_title('SLR ($cm \cdot yr^{-1}$)',  #文本                     pad=15,  # 距离                     fontsize=16)  # 字体大小

第九部分

双向子弹图+百分比环图组合图绘制函数:中间文本列设置

    ax_mid.set_ylim(-0.8, len(df) - 0.2)  # 中间子图y轴范围    ax_mid.axis('off')  # 关闭坐标轴显示    for i, name in enumerate(df['Delta']):  # 遍历称        ax_mid.text(0.5,  # x坐标                    i,  # y坐标                    name,  # 文本                    ha='center',  # 水平                    va='center',  # 垂直                    fontsize=16,  # 字体                    color='black')  # 颜色

第十部分

双向子弹图+百分比环图组合图绘制函数:内嵌饼图绘制、图例绘制、箭头设置、结果保存

   # 调用绘制饼图函数    draw_styled_pie_chart(fig,                          [0.13,  # 左                           0.12,#下                           0.28,#宽                           0.30],#高                          df_pie)  # 数据    # 调用图例函数    draw_combined_legend(fig,  [0.15, 0.45,0.14, 0.14])     #子标题    fig.text(0.12,  # x             0.92,  # y             'c',  # 文本             fontsize=24,  # 字体大小             fontweight='bold')  # 粗体    plt.subplots_adjust(wspace=0.01)  # 调整子图间距

第十一部分

执行部分

# =========================================================================================# ======================================6.执行部分=======================================# =========================================================================================if __name__ == "__main__":    excel_filename = r'Data.xlsx'  # 文件路径    df_bar = pd.read_excel(excel_filename, sheet_name='Bar_Data')  # 读取柱状图数据    df_pie_data = pd.read_excel(excel_filename, sheet_name='Pie_Data')  # 读取饼图数据    df_data = df_bar.iloc[::-1].reset_index(drop=True)  # 数据反转    plot_delta_chart(df_data, df_pie_data)  # 调用绘图函数

如何应用到你自己的数据

1.设置颜色方案:

SCHEME_ID = 40  #选择配色方案

2.提取百分比环形图数据:

labels = df_pie['Continent'].tolist()  # 获取标签sizes_max = df_pie['Max_Percent'].tolist()  # 获取最大百分比数据sizes_95 = df_pie['95th_Percent'].tolist()  # 获取95分位数百分比数据

3.设置绘图结果的保存路径:

plt.savefig(fr'{SCHEME_ID}.png', dpi=300, bbox_inches='tight')plt.savefig(fr'{SCHEME_ID}.pdf', format='pdf', bbox_inches='tight')

4.设置原始数据的路径:

excel_filename = r'_Data.xlsx'  # 文件路径

推荐

期刊图片复现|Python绘制二维偏依赖PDP图
期刊复现|python绘制基于SHAP分析和GAM模型拟合的单特征依赖图
期刊图片复现|python绘制带有渐变颜色shap特征重要性组合图(条形图+蜂巢图)
期刊复现|用Python绘制SHAP特征重要性总览图、依赖图、双特征交互效应SHAP图,解锁XGBoost模型的终极奥秘
期刊图片复现|Python绘制shap重要性蜂巢图+单特征依赖图+交互效应强度气泡图+交互效应依赖图(回归+二分类+分类)

获取方式

公众号中的所有所有的免费代码都已经下架了,都并入到付费部分里了,付费合集代码和数据的购买通道已经开通,全部合集100元,后续将会持续更新,决定购买请后台私信我,注意只会分享练习数据和代码文件,不会提供答疑服务,代码文件中已经包含了每行代码的完整注释,购买前请确保真的需要!!!

最新文章

随机文章