如何在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
相关产品推荐
相关产品推荐

