Python Matplotlib嵌套饼图:4行4列布局与图例标签设置方法
Matplotlib 嵌套饼图修正实现方案
原有代码核心缺陷
- 内层饼图未按照外层SEX的分组顺序对齐数值,会出现扇区跨边界错位的问题
- 所有标签直接堆叠在扇区上,展示杂乱,不符合将标签移至图例区域的要求
- 没有预留图例布局空间,无法实现4行4列的规整排版
分步实现逻辑
1. 数据预处理与扇区对齐
嵌套饼图的内层扇区必须严格匹配外层分组的角度边界,需要先固定分组顺序再拆分内外层数值:
import pandas as pd import matplotlib.pyplot as plt # 固定外层SEX的分组顺序,避免扇区角度偏移 outer_group = df.groupby('SEX')['count'].sum() outer_values = outer_group.values outer_labels = outer_group.index.tolist() # 内层数据按照外层SEX的分组顺序连续排列,保证扇区完全对齐 inner_df = df.set_index('SEX').loc[outer_group.index].reset_index() inner_values = inner_df['count'].values inner_labels = inner_df['ALIGN'].tolist()
2. 绘制嵌套饼图并关闭扇区直接标签
按照从外到内为SEX、ALIGN的要求绘制两层饼图,关闭直接打在扇区上的标签,将计数直接标注在扇区上:
size = 0.3 fig, ax = plt.subplots(figsize=(24, 12)) # 绘制外层SEX层 outer_wedges, _, outer_autotexts = ax.pie( outer_values, radius=1, labels=None, # 关闭扇区上的直接标签,标签后续移至图例 autopct=lambda p: f'{round(p * sum(outer_values)/100)}', # 扇区上直接展示对应计数值 wedgeprops=dict(width=size, edgecolor='w') ) # 绘制内层ALIGN层 inner_wedges, _ = ax.pie( inner_values, radius=1 - size, labels=None, # 关闭扇区上的直接标签 wedgeprops=dict(width=size, edgecolor='w') ) ax.set(aspect="equal", title='角色性别与阵营分布嵌套饼图')
3. 实现4行4列的图例布局
将内外层的分类标签统一整合到图例区,补充占位元素凑满4行4列的16个网格槽位,保证布局规整:
# 合并内外层楔形对象和对应标签 all_wedges = outer_wedges + inner_wedges all_labels = [f'外层 | {label}' for label in outer_labels] + [f'内层 | {label}' for label in inner_labels] # 补充无内容的占位元素,凑满4行4列共16个网格槽位 while len(all_wedges) < 16: placeholder = plt.matplotlib.patches.Patch(facecolor='none', edgecolor='none') all_wedges.append(placeholder) all_labels.append('') # 按4列设置网格,自然形成4行的规整布局 ax.legend( all_wedges, all_labels, loc='center left', bbox_to_anchor=(1.05, 0.5), # 锚定在主图右侧区域,避免遮挡饼图 ncol=4, # 4列排布,16个元素刚好形成4行网格,实现4行4列的槽位布局 fontsize=10, title='分类标签说明' ) # 调整边距给图例预留空间 plt.tight_layout() plt.show()
实现效果说明
- 扇区严格对齐的逻辑可以避免内层ALIGN扇区跨外层SEX边界的错位问题
- 自定义autopct逻辑会在每个扇区上直接标注实际计数值,满足计数展示需求
- 补充占位元素后,图例区严格形成4行4列的网格布局,16个槽位全部占位,排版整齐
- 所有分类标签全部移至图例区,不会在扇区上造成文字堆叠遮挡
内容的提问来源于stack exchange,提问作者Sercan Noyan Germiyanoğlu
相关产品推荐
相关产品推荐

