You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何消除其他子图刻度标签造成的色条左侧内边距并居中色条

如何消除其他子图刻度标签造成的色条左侧内边距并居中色条

看起来你遇到的问题真的很烦人——明明色条不需要给Y轴标签留空间,却被整个网格的布局带着走,左边多了一大块空白对吧?我来给你两个亲测有效的解决思路,都是针对你的代码结构调整的:

方法一:手动指定色条位置(最直接可控)

既然constrained layout的自动布局会把色条绑定到网格的padding上,那我们干脆跳出这个约束,手动给色条找个居中的位置。只要去掉layout="constrained",用tight_layout()预留空间,再手动创建色条的轴就行:

修改后的核心代码:

fig = plt.figure(figsize=(12, 13))  # 去掉layout="constrained",避免自动布局干扰

def render_heatmaps():
    nrows = len(domain_knowledge["DS1: Automotive"]) + 2
    ncols = len(domain_knowledge.keys())
    gs = fig.add_gridspec(nrows, ncols)
    gs.set_height_ratios([0.7, 1, 1, 1, 1, 0.1])
    gs.hspace = 0.07
    gs.wspace = 0.02

    # 渲染infobox(这部分和你原来的代码一样)
    ax_text: Axes = fig.add_subplot(gs[0, :])
    render_infobox(ax_text)

    # 归一化和颜色映射(不变)
    norm = mcolors.Normalize(vmin=np.min(datasets), vmax=np.max(datasets))
    colors = ScalarMappable(norm, cmap="GnBu")

    # 渲染热图(这部分和你原来的代码一样)
    for row in range(nrows - 2):
        for col in range(ncols):
            axis = fig.add_subplot(gs[row + 1, col])
            sns.heatmap(
                datasets[col * 4 + row],
                annot=True,
                cmap=colors.cmap,
                yticklabels=(categories_necessity[:nec_range] if col == 0 else False),
                xticklabels=(
                    categories_temporality[:temp_range]
                    if row + 1 == nrows - 2
                    else False
                ),
                ax=axis,
                cbar=False,
            )
            axis.tick_params(axis="y", labelrotation=0)
            axis.set_title(label=f"S{col*4+row}")

    # 重点:手动创建色条轴并居中
    # 先调用tight_layout预留底部空间给色条
    plt.tight_layout(rect=[0, 0.05, 1, 0.98])  # rect=[左, 下, 右, 上],底部留0.05的高度
    # 手动指定色条位置:x从0.15到0.85(宽度0.7),y在0.01,高度0.03
    cax = fig.add_axes([0.15, 0.01, 0.7, 0.03])
    fig.colorbar(colors, cax=cax, orientation="horizontal")
    cax.set_title("Number of Study Responses")
    # 隐藏色条的Y轴(本来就不需要)
    cax.yaxis.set_visible(False)

这个方法的好处是你完全可以控制色条的位置,调整[0.15, 0.01, 0.7, 0.03]里的数值就能精准居中,左边的空白直接消失。

方法二:用嵌套Gridspec分离色条布局

如果你不想放弃constrained layout,可以把热图区域和色条区域分成两个独立的Gridspec,给色条单独设置布局参数,让它不受第一列Y轴标签的影响:

fig = plt.figure(figsize=(12, 13), layout="constrained")

def render_heatmaps():
    # 主热图区域:nrows-1行(去掉色条的那一行)
    nrows_main = len(domain_knowledge["DS1: Automotive"]) + 1  # 原来的4+1(infobox+4个热图行)
    ncols = len(domain_knowledge.keys())
    main_gs = fig.add_gridspec(nrows_main, ncols, height_ratios=[0.7, 1, 1, 1, 1])
    main_gs.hspace = 0.07
    main_gs.wspace = 0.02

    # 渲染infobox
    ax_text: Axes = fig.add_subplot(main_gs[0, :])
    render_infobox(ax_text)

    norm = mcolors.Normalize(vmin=np.min(datasets), vmax=np.max(datasets))
    colors = ScalarMappable(norm, cmap="GnBu")

    # 渲染热图(循环范围调整为nrows_main-1行,因为main_gs第一行是infobox)
    for row in range(nrows_main - 1):
        for col in range(ncols):
            axis = fig.add_subplot(main_gs[row + 1, col])
            sns.heatmap(
                datasets[col * 4 + row],
                annot=True,
                cmap=colors.cmap,
                yticklabels=(categories_necessity[:nec_range] if col == 0 else False),
                xticklabels=(
                    categories_temporality[:temp_range]
                    if row + 1 == nrows_main - 1
                    else False
                ),
                ax=axis,
                cbar=False,
            )
            axis.tick_params(axis="y", labelrotation=0)
            axis.set_title(label=f"S{col*4+row}")

    # 色条区域:单独一个Gridspec,调整左右边距让它居中
    cbar_gs = fig.add_gridspec(1, ncols, height_ratios=[0.1])
    cbar_gs.update(left=0.1, right=0.9, hspace=0.0)  # 强制色条在0.1到0.9的水平范围内
    cax = fig.add_subplot(cbar_gs[0, :])
    fig.colorbar(colors, cax=cax, orientation="horizontal")
    cax.set_title("Number of Study Responses")
    cax.yaxis.set_visible(False)  # 隐藏不需要的Y轴

这个方法保持了constrained layout的优势,同时让色条的布局独立于热图区域,通过cbar_gs.update(left=0.1, right=0.9)直接把色条的左右边界固定,去掉左侧多余的padding。

为什么你之前的方法没用?

你之前试的cax.set_yticks([])或者set_xmargin(0)没用,是因为问题根本不在色条的刻度上——而是整个网格布局为了给第一列的Y轴标签留空间,给所有子图(包括色条)都加上了左侧padding。只有把色条从这个共享的布局约束里解放出来,才能真正去掉左边的空白~

备注:内容来源于stack exchange,提问作者Mayor Mayer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 19:44:32