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

如何在Matplotlib饼图中实现单标签分两列的图例

解决Matplotlib饼图图例两列对齐(名称与百分比分隔)的问题

当使用非等宽自定义字体时,靠补充空格对齐图例标签的方法会失效,这里提供两种可靠的解决方案:


方法一:用OffsetBox创建双列对齐图例项

通过OffsetBox将名称(左对齐)和百分比(右对齐)组合成单个图例条目,彻底摆脱字体宽度的影响,确保两列整齐分隔。

完整代码示例:

import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import pandas as pd
from matplotlib.offsetbox import OffsetBox, TextArea, HPacker

data = {'names': ['North America', 'Europe', 'Japan', 'Emerging Asia', 'Latin America', 'Cash'],
        'values': [76, 14, 4, 4, 0, 3]}
df = pd.DataFrame(data)

fig, ax = plt.subplots()

ax.pie(
    df['values'], 
    startangle=90, 
    wedgeprops={'width': 0.3},
)

# 若使用自定义字体,直接在这里指定路径即可
font_properties = fm.FontProperties()  # 示例:fm.FontProperties(fname='your_custom_font.ttf')

def make_legend_entry(name, value, fontprops):
    # 创建左对齐的名称文本框
    name_box = TextArea(name, textprops={'fontproperties': fontprops, 'ha': 'left'})
    # 创建右对齐的百分比文本框
    value_box = TextArea(f'{value}%', textprops={'fontproperties': fontprops, 'ha': 'right'})
    # 水平打包两个文本框,设置间距
    return HPacker(children=[name_box, value_box], align='center', pad=5, sep=20)

# 生成所有图例条目
legend_entries = [make_legend_entry(n, v, font_properties) for n, v in zip(df['names'], df['values'])]

# 生成图例:用矩形占位,通过handler_map绑定自定义条目
ax.legend(
    handles=[plt.Rectangle((0,0),1,1) for _ in df['names']],
    labels=legend_entries,
    handler_map={plt.Rectangle: lambda handle, label: label},
    bbox_to_anchor=(0.7, 0.1)
)

plt.show()

方法二:手动绘制图例(高度自定义)

如果需要更精细的布局控制,可以直接在图中手动绘制颜色块、名称和百分比,通过固定x坐标实现严格对齐。

核心代码片段(替换原图例部分):

# 获取饼图各块的颜色
colors = [w.get_facecolor() for w in ax.patches]

# 设置图例的起始位置
legend_x = 1.2
legend_y = 0.5

# 遍历每个条目绘制元素
for i, (name, value, color) in enumerate(zip(df['names'], df['values'], colors)):
    # 绘制颜色块
    ax.add_patch(plt.Rectangle((legend_x, legend_y - i*0.1), 0.1, 0.08, color=color))
    # 绘制左对齐的名称
    ax.text(legend_x + 0.12, legend_y - i*0.1 + 0.04, name, fontproperties=font_properties, ha='left')
    # 绘制右对齐的百分比,固定x坐标保证对齐
    ax.text(legend_x + 2.0, legend_y - i*0.1 + 0.04, f'{value}%', fontproperties=font_properties, ha='right')

# 调整坐标轴范围,确保图例完整显示
ax.set_xlim(-1.5, 2.5)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:33:13