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

如何在Python中使用plt.legend为图例添加列标题?

实现带列标题的Matplotlib图例

没问题!要给这种分两组(实心/空心标记对应不同属性)的图例加上列标题,用matplotlib的plt.legend完全可以实现,核心思路是用虚拟图例条目做标题,再重组图例的条目布局,我给你写个可直接运行的示例,一步步讲清楚:

核心思路

  1. 先正常绘制所有曲线(每种材料的实心、空心曲线)
  2. 创建两个「虚拟的图例条目」(空线条+空标记)作为两列的标题
  3. 把原有图例条目拆分为「实心组」和「空心组」
  4. 重组图例条目:标题+对应组,设置ncol=2让内容分成两列
  5. 调整样式让标题看起来更像列头

完整代码示例

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

# 模拟数据:3种材料,每种对应「属性A(实心)」和「属性B(空心)」两条曲线
materials = ["材料1", "材料2", "材料3"]
x = [1, 2, 3, 4]

# 第一步:绘制所有曲线
fig, ax = plt.subplots(figsize=(8, 5))
for idx, mat in enumerate(materials):
    # 实心标记:属性A
    ax.plot(x, [idx + val for val in x], 
            marker='o', linestyle='-', color=f'C{idx}', label=mat)
    # 空心标记:属性B
    ax.plot(x, [idx + val + 0.6 for val in x], 
            marker='o', linestyle='--', color=f'C{idx}', 
            markerfacecolor='white', label=mat)

# 第二步:创建虚拟图例条目作为列标题(只显示文字,无标记/线条)
title_style = {'weight': 'bold', 'fontsize': 10}
title_attr_a = Line2D([], [], label='属性A', linestyle='', marker='', **title_style)
title_attr_b = Line2D([], [], label='属性B', linestyle='', marker='', **title_style)

# 第三步:提取原有图例的handles和labels,并拆分两组
all_handles, all_labels = ax.get_legend_handles_labels()
# 拆分:偶数索引是实心(属性A),奇数是空心(属性B)
handles_attr_a = all_handles[::2]
labels_attr_a = all_labels[::2]
handles_attr_b = all_handles[1::2]
labels_attr_b = all_labels[1::2]

# 第四步:重组图例条目,让标题对应各自的组
new_handles = [title_attr_a] + handles_attr_a + [title_attr_b] + handles_attr_b
new_labels = [title_attr_a.get_label()] + labels_attr_a + [title_attr_b.get_label()] + labels_attr_b

# 第五步:创建图例并调整布局
legend = ax.legend(
    handles=new_handles,
    labels=new_labels,
    ncol=2,
    handlelength=0,  # 隐藏虚拟标题的空标记
    handletextpad=0,
    columnspacing=4,  # 调整两列之间的间距
    loc='upper left'
)

# 可选:微调标题位置,让它和下方条目区分开
for text in legend.get_texts():
    if text.get_text() in ['属性A', '属性B']:
        text.set_position((0, 12))  # 向上移动标题,增强列头感

plt.tight_layout()
plt.show()

关键细节说明

  • 虚拟条目:用Line2D创建没有线条和标记的对象,只保留label作为标题,这样能完美融入图例布局
  • 条目拆分:因为我们绘图时是先画实心再画空心,所以可以用步长索引[::2]和[1::2]拆分两组
  • 样式调整:handlelength=0避免虚拟标题显示空标记,columnspacing控制列间距,最后手动移动标题位置让布局更协调

运行这段代码后,你就能得到带有「属性A」「属性B」列标题的图例,正好对应实心/空心标记的分组~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 12:52:32