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

Matplotlib中固定绘图尺寸与X轴位置并预留图例空间

解决Matplotlib图例导致绘图尺寸/轴位置变化的问题

问题描述

  • 无图例时,绘图尺寸为设定的figsize;
  • 添加无标题图例时,绘图底部会扩展以容纳图例;
  • 添加带标题图例时扩展幅度更大;
  • 若使用tight_layout,绘图尺寸不变但X轴会向上偏移。

需求:在绘图底部与X轴之间预留足够空间,使得无论是否添加带/不带标题的图例,绘图的像素尺寸和轴位置都保持不变。尝试过tight_layout和subplot_adjust,但未达到预期效果。

用户提供的测试代码

import matplotlib.pyplot as plt

def set_legend(ax, item_count, title=None):
    legend = ax.legend(
        title=title,
        loc='upper center',
        bbox_to_anchor=(0.5, -0.1),
        ncol=item_count,
        frameon=False,
        prop={'size': 6}
    )
    legend.get_title().set_fontsize('8')
    return ax
  
def generate_plot_base():
    fig, ax = plt.subplots(1, 1, figsize=(6, 2.71), tight_layout={'pad': 0})
    return ax

ax = generate_plot_base()
ax.plot([], [], label='Label 1', color='blue')  # Toy labels
ax.plot([], [], label='Label 2', color='orange')
ax.plot([], [], label='Label 3', color='green')
ax = set_legend(ax, 3, title="Example Legend") # 注释此行后X轴会下移
plt.show()

解决方案

核心思路是提前在绘图底部预留足够容纳最大图例(带标题)的固定空间,让图例仅占用预留区域,不改变坐标轴位置和整体画布尺寸。

方法1:通过gridspec_kw预设底部留白

修改generate_plot_base函数,直接在创建子图时指定底部留白比例:

import matplotlib.pyplot as plt

def set_legend(ax, item_count, title=None):
    legend = ax.legend(
        title=title,
        loc='upper center',
        bbox_to_anchor=(0.5, -0.1),
        ncol=item_count,
        frameon=False,
        prop={'size': 6}
    )
    legend.get_title().set_fontsize('8')
    return ax
  
def generate_plot_base():
    # bottom=0.2 表示子图底部距离画布底部保留20%的空间,可根据图例大小调整
    fig, ax = plt.subplots(1, 1, figsize=(6, 2.71), 
                          gridspec_kw={'bottom': 0.2}, tight_layout=False)
    return ax

# 测试无图例场景
ax = generate_plot_base()
ax.plot([], [], color='blue')
ax.plot([], [], color='orange')
ax.plot([], [], color='green')
plt.show()

# 测试带标题图例场景
ax = generate_plot_base()
ax.plot([], [], label='Label 1', color='blue')
ax.plot([], [], label='Label 2', color='orange')
ax.plot([], [], label='Label 3', color='green')
ax = set_legend(ax, 3, title="Example Legend")
plt.show()

方法2:手动固定子图位置

如果gridspec_kw不够灵活,可在生成子图后直接调用subplots_adjust锁定底部位置:

def generate_plot_base():
    fig, ax = plt.subplots(1, 1, figsize=(6, 2.71), tight_layout=False)
    # 直接设置子图位置参数,bottom取值0-1(相对画布比例)
    fig.subplots_adjust(bottom=0.2)
    return ax

关键注意事项

  • 必须关闭tight_layout,避免它自动调整子图位置导致轴偏移;
  • bottom的具体数值可根据实际图例大小微调,确保带标题的图例能完全容纳在预留空间内;
  • 两种方法都能实现:无论是否添加图例,坐标轴位置和整体画布尺寸完全一致。

内容的提问来源于stack exchange,提问作者Moran Reznik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:22:36