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

如何绘制无重叠标签的Matplotlib饼图?现有代码问题排查与解决建议

解决Matplotlib饼图标签重叠问题

嘿,我看你是因为类别数量偏多,再加上图例布局没做针对性优化,才导致标签挤在一起重叠了。我给你几个实用的解决思路,同时修正你的代码:

核心问题分析

你的代码把带百分比的标签全放到了左侧图例里,当类别超过10个时,垂直排列的图例很容易出现标签堆叠重叠。另外,plt.pie默认的标签位置和图例配合逻辑,没有针对多类别场景做适配。

解决思路与代码修正

1. 优化图例布局:设置多列排列

给plt.legend加上ncol参数,把图例拆分成多列,减少垂直方向的拥挤;再配合tight_layout()自动调整整体布局,防止内容被截断:

import numpy as np
import matplotlib.pyplot as plt
from collections import Counter

# 假设data是你的数据源
count_legalgroups = Counter(data['LegalFormGroup']).most_common()
for_dict = dict(count_legalgroups)
legal_from_list = list(for_dict.keys())
count_from_list = list(for_dict.values())
slices = np.array(count_from_list)
activities = np.array(legal_from_list)
colors = ['yellowgreen','red','gold','lightskyblue','lightcoral','blue','pink', 'darkgreen','grey','violet','magenta','cyan', 'brown']

patches, texts = plt.pie(slices, colors=colors, startangle=90, labels=activities)
labels = ['{0} - {1:1.2f} %'.format(i, j) for i, j in zip(activities, 100.*slices/slices.sum())]

# 新增ncol=2让图例分成两列,同时微调锚点位置
plt.legend(patches, labels, loc='upper left', bbox_to_anchor=(-0.5, 1), fontsize=8, ncol=2)
plt.tight_layout()  # 自动适配布局,避免内容被裁掉
plt.show()

2. 直接在饼块旁显示百分比,简化图例

用autopct参数把百分比直接标在饼块旁边,图例只保留类别名称,能大幅减少标签拥挤的情况;同时用labeldistance调整标签和饼块的距离:

import numpy as np
import matplotlib.pyplot as plt
from collections import Counter

count_legalgroups = Counter(data['LegalFormGroup']).most_common()
for_dict = dict(count_legalgroups)
legal_from_list = list(for_dict.keys())
count_from_list = list(for_dict.values())
slices = np.array(count_from_list)
activities = np.array(legal_from_list)
colors = ['yellowgreen','red','gold','lightskyblue','lightcoral','blue','pink', 'darkgreen','grey','violet','magenta','cyan', 'brown']

# 用autopct显示百分比,labeldistance让标签远离饼块避免重叠
patches, texts, autotexts = plt.pie(slices, colors=colors, startangle=90, 
                                    labels=activities, autopct='%1.1f%%',
                                    labeldistance=1.1)

# 图例只保留类别名称,放在合适位置
plt.legend(patches, activities, loc='center left', bbox_to_anchor=(-0.4, 0.5), fontsize=8)
plt.tight_layout()
plt.show()

3. 合并小类别(推荐方案)

如果某些类别的占比极小,直接合并成「其他」类别,从根源上减少标签数量,彻底解决重叠问题:

import numpy as np
import matplotlib.pyplot as plt
from collections import Counter

count_legalgroups = Counter(data['LegalFormGroup']).most_common()
# 合并占比小于5%的类别
total = sum([v for k, v in count_legalgroups])
threshold = 0.05 * total
filtered = [(k, v) for k, v in count_legalgroups if v >= threshold]
other_sum = sum([v for k, v in count_legalgroups if v < threshold])
if other_sum > 0:
    filtered.append(('其他', other_sum))

for_dict = dict(filtered)
legal_from_list = list(for_dict.keys())
count_from_list = list(for_dict.values())
slices = np.array(count_from_list)
activities = np.array(legal_from_list)
colors = ['yellowgreen','red','gold','lightskyblue','lightcoral','blue','pink', 'darkgreen']

patches, texts = plt.pie(slices, colors=colors, startangle=90, labels=activities)
labels = ['{0} - {1:1.2f} %'.format(i, j) for i, j in zip(activities, 100.*slices/slices.sum())]

plt.legend(patches, labels, loc='center left', bbox_to_anchor=(-0.35, .5), fontsize=8)
plt.tight_layout()
plt.show()

你代码里遗漏的关键设置

  • 没给图例加ncol参数分散标签
  • 没使用labeldistance调整饼图标签与饼块的距离
  • 没考虑合并小类别减少标签总数
  • 缺少plt.tight_layout()自动调整整体布局,容易导致内容被截断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 08:52:43