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

Matplotlib多列图例中添加无标记左对齐标签的方法

解决Matplotlib多列图例中添加左对齐无标记参数标签的问题

需求与问题

需要在Matplotlib图例中添加带参数值的无标记标签,要求:

  • 标签左对齐
  • 标签文本的起始位置与其他带标记的图例条目处于同一列

单列图例可通过设置图例标题实现,但当图例为2列及以上时,标题会导致第二列首个条目与第一列首个条目同行,无法满足参数标签独占一行、后续条目按列排列的需求。

解决方案

方法1:自定义图例Handler实现跨列(推荐,兼容性好)

通过自定义HandlerBase子类,让参数标签文本占据图例整行宽度,实现跨列效果,同时保持左对齐。

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
from matplotlib.legend_handler import HandlerBase

# 自定义跨列图例处理器,让文本占据整行
class HandlerSpanColumn(HandlerBase):
    def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans):
        # 创建左对齐的文本,垂直居中
        text = plt.Text(xdescent, ydescent + height/2, orig_handle.get_label(), 
                        ha='left', va='center', fontsize=fontsize)
        return [text]

# 绘制空线条用于图例
plt.plot([], [], linestyle='--', color='black', label='Dashed Line')
plt.plot([], [], linestyle=':', color='black', label='Dotted Line')
plt.plot([], [], linestyle='-', linewidth=2, color='black', label='Double Solid Line')
plt.plot([], [], linestyle='-.', color='black', label='Dash-Dot Line')

# 创建带标记的图例条目
legend_ETP = Line2D([0], [0], marker='o', c='k', ls='None', markerfacecolor='k', markersize=8, label="Far")
legend_IOTP = Line2D([0], [0], marker='s', c='k', ls='None', markerfacecolor='k', markersize=8, label="Near")
# 创建参数标签的无标记条目
legend_param = Line2D([0], [0], marker='', ls='None', label="Exact = 0.5")

# 获取原有图例条目
ELS_handles, ELS_labels = plt.gca().get_legend_handles_labels()

# 组合所有图例条目,参数标签放在最前面
new_handles = [legend_param, legend_ETP, legend_IOTP] + ELS_handles
new_labels = ["Exact = 0.5", "Far", "Near"] + ELS_labels

# 指定参数标签使用自定义处理器
handler_map = {legend_param: HandlerSpanColumn()}
legend = plt.legend(handles=new_handles, labels=new_labels, fontsize=12, loc='lower left', 
                    ncol=2, handler_map=handler_map)

# 设置图例整体左对齐
legend._legend_box.align = "left"

plt.show()

方法2:手动调整图例布局(简单但依赖内部结构)

通过直接修改图例内部布局,将参数标签条目宽度设为图例整行宽度,实现跨列。

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

# 绘制空线条用于图例
plt.plot([], [], linestyle='--', color='black', label='Dashed Line')
plt.plot([], [], linestyle=':', color='black', label='Dotted Line')
plt.plot([], [], linestyle='-', linewidth=2, color='black', label='Double Solid Line')
plt.plot([], [], linestyle='-.', color='black', label='Dash-Dot Line')

# 创建带标记的图例条目
legend_ETP = Line2D([0], [0], marker='o', c='k', ls='None', markerfacecolor='k', markersize=8, label="Far")
legend_IOTP = Line2D([0], [0], marker='s', c='k', ls='None', markerfacecolor='k', markersize=8, label="Near")
# 创建参数标签的无标记条目
legend_void = Line2D([0], [0], marker='', ls='None', label="Exact = 0.5")

# 获取原有图例条目
ELS_handles, ELS_labels = plt.gca().get_legend_handles_labels()

# 组合所有图例条目,参数标签放在最前面
new_handles = [legend_void, legend_ETP, legend_IOTP] + ELS_handles
new_labels = ["Exact = 0.5", "Far", "Near"] + ELS_labels

# 创建图例
legend = plt.legend(handles=new_handles, labels=new_labels, fontsize=12, loc='lower left', ncol=2)
legend._legend_box.align = "left"

# 手动调整第一个条目宽度,使其跨两列
box = legend._legend_box.get_children()[1]  # 获取存放图例条目的容器
box.get_children()[0].set_width(box.get_width())  # 将第一个条目宽度设为容器总宽度

plt.show()

效果说明

两种方法均可实现:

  • 参数标签Exact = 0.5左对齐,文本起始位置与其他带标记的条目保持一致
  • 参数标签独占一行,第二列的首个条目会排在参数标签的下一行,而非与第一列的Far同行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:53:15