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

如何在matplotlib的ax.legend中为每个图例标签添加换行符

问题描述

想要修改所绘堆叠条形图的图例,在每个图例标签后添加换行符,避免长标签挤压显示空间。现有两个不可修改的字典,分别存储绘图数值、图例标签与对应颜色的映射关系。
原有实现代码如下:

import numpy as np
import matplotlib.pyplot as plt
text_color = "white"

dico_valeur = {'A': [5, 2, 2, 6, 2, 0, 0, 1],
 'B': [6, 5, 0, 0, 0, 0, 1, 0],
 'C': [6, 22, 2, 5, 3, 1, 2, 1],
 'D': [13, 3, 2, 1, 3, 0, 0, 0],
 'E': [14, 6, 12, 1, 4, 2, 2, 0],
 'F': [3, 3, 0, 0, 0, 1, 0, 0],
 'G': [6, 11, 3, 6, 1, 0, 1, 1],
 'H': [3, 2, 2, 1, 3, 0, 0, 1],
 'I': [2, 0, 0, 0, 0, 1, 0, 0],
 'J': [6, 10, 1, 5, 3, 1, 0, 0],
 'K': [2, 4, 1, 1, 0, 0, 0, 0],
 'L': [1, 0, 0, 0, 0, 0, 0, 0],
 'M': [1, 0, 0, 0, 0, 0, 0, 0],
 'N': [10, 7, 2, 3, 3, 3, 0, 0]}

dico_couleur = {"a very very very very very very very very very very very very very very very very very very very very long legend": 'C0',
 'another very very very very very very very very very very very very very very very very very very very very long legend, démarreur,…': 'C1',
 'a very very very very very very very very very very very very very very very very very long legend': 'C2',
 "a very very very very very very very very very very very very very very very vry very very very long legend": 'C3',
 'a very very very very very veryy very very very very very very long legend': 'C4',
 'a very very very very very very very very very very very very very very very very very very very very long legend': 'C5',
 "a very very very very very very very very very very very very very very very very very very long legend": 'C6',
 'a very very very very very very very very veryery very very very very very very very very long legend': 'C7'}

category_names = []
for i in dico_couleur: category_names.append(i)
results = dico_valeur
labels = list(results.keys())
data = np.array(list(results.values()))
data_cum = data.cumsum(axis=1)
category_colors = list(dico_couleur.values())

fig, ax = plt.subplots(figsize=(15, 7))
ax.invert_yaxis()
ax.xaxis.set_visible(False)
ax.set_xlim(0, np.sum(data, axis=1).max())

for i, (colname, color) in enumerate(zip(category_names, category_colors)):
    widths = data[:, i]
    starts = data_cum[:, i] - widths
    ax.barh(labels, widths, left=starts, height=0.5,
            label=colname, color=color)
    xcenters = starts + widths / 2


    for y, (x, c) in enumerate(zip(xcenters, widths)):
        if c != 0:
            ax.text(x, y, str(int(c)), ha='center', va='center',
                        color=text_color)
ax.legend(ncol=len(category_names), bbox_to_anchor=(1, 0, 0.5, 1),
          loc='lower left', fontsize='small')

plt.show()

当前问题:运行代码后长图例标签横向排列过于拥挤,找不到为每个标签添加换行符的实现方法。

解决思路

由于无需修改原始字典,仅需要在读取图例标签生成category_names时对字符串做加工即可,不需要改动原始数据:

  • 方案1:直接为每个标签末尾添加换行符
    把原有生成category_names的逻辑替换为如下写法即可,每个标签末尾会自动追加换行符,撑开纵向显示空间:
category_names = [label + "\n" for label in dico_couleur.keys()]
  • 方案2:自动按字数折行长标签(优化显示效果)
    如果标签过长,仅加末尾换行还是会占用过多横向宽度,可以自定义折行逻辑,按指定字数拆分标签插入换行符:
def add_line_break(text, max_len=15):
    # 按指定最大长度拆分文本插入换行
    res = []
    for i in range(0, len(text), max_len):
        res.append(text[i:i+max_len])
    return "\n".join(res)

category_names = [add_line_break(label) for label in dico_couleur.keys()]

额外优化建议:原有图例参数ncol=len(category_names)强制所有图例横向排列,本身就会导致长标签拥挤,可根据调整后的标签长度适当减小ncol数值,比如设为1或2,显示效果会更合理:

ax.legend(ncol=2, bbox_to_anchor=(1, 0, 0.5, 1),
          loc='lower left', fontsize='small')

内容的提问来源于stack exchange,提问作者mathieu e.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 07:06:03