如何实现嵌套饼图外层与内层匹配及目标配色设置
嵌套饼图内外层匹配与配色优化方案
问题描述
尝试绘制嵌套饼图(目标效果如图),但当前生成的饼图存在两个问题:外层环与内部分组的分段不对应,且配色不符合预期。


数据集
Console Type Company Release Units_sold 0 PlayStation 2 Home Sony 2000 155000000 1 Nintendo DS Handheld Nintendo 2004 154002000 2 Nintendo Switch Hybrid Nintendo 2017 122550000 3 Game Boy Handheld Nintendo 1989 118690000 4 PlayStation 4 Home Sony 2013 117200000 5 PlayStation Home Sony 1994 102490000 6 Wii Home Nintendo 2006 101630000 7 PlayStation 3 Home Sony 2006 87400000 8 Xbox 360 Home Microsoft 2005 84000000 9 PlayStation Portable Handheld Sony 2004 82000000 10 Game Boy Advance Handheld Nintendo 2001 81510000 11 Nintendo 3DS Handheld Nintendo 2011 75940000 12 NES Home Nintendo 1983 61910000 13 Xbox One Home Microsoft 2013 58500000 14 SNES Home Nintendo 1990 49100000 15 Nintendo 64 Home Nintendo 1996 32930000 16 PlayStation 5 Home Sony 2020 32100000 17 Xbox Home Microsoft 2001 24000000 18 GameCube Home Nintendo 2001 21740000 19 Xbox Series X/S Home Microsoft 2020 18500000 20 PlayStation Vita Handheld Sony 2011 15000000 21 Wii U Home Nintendo 2012 13560000 22 SNES Classic Dedicated Nintendo 2017 5280000 23 NES Classic Dedicated Nintendo 2016 3560000 24 Color TV-Game Dedicated Nintendo 1977 3000000
当前代码
df_3_outer = df_3.sort_values('Company').reset_index() # only keep the console and units_sold columns df_3_outer = df_3_outer[['Console', 'Units_sold']] df_3_inner = df_3.groupby(['Company'])['Units_sold'].sum().reset_index() fig, ax = plt.subplots(figsize=(9,6)) inner_colors = ['#156EAF', '#DB2018', '#56B45B'] outer_colors =['#5599CC', '#EA6727', '#83C143'] outer_colors[labels.index('')] size = 0.8 r = 2 ax.pie(df_3_outer['Units_sold'], labels=df_3_outer.Console, radius=r, colors=outer_colors, wedgeprops=dict(width=size, edgecolor='w')) ax.pie(df_3_inner.Units_sold, labels=df_3_inner.Company, radius=r-size, colors=inner_colors, labeldistance=0.6, textprops=dict(color="w", fontsize=15), )
解决方案
1. 核心问题分析
- 内外层分段不匹配:外层仅按
Company排序,但groupby默认会对分组键排序,需保证外层的控制台顺序与内层分组顺序完全一致(同一公司的控制台连续排列,且公司顺序与内层groupby结果一致)。 - 配色混乱:当前固定的
outer_colors列表无法对应每个控制台所属公司,需为每个公司分配专属色系,外层用对应公司的浅色调,内层用深色调。
2. 修改后的完整代码
import matplotlib.pyplot as plt import pandas as pd # 按Company排序,确保同一公司的控制台连续,与groupby结果顺序一致 df_3_outer = df_3.sort_values('Company').reset_index(drop=True) df_3_outer = df_3_outer[['Console', 'Units_sold', 'Company']] # 内层分组求和,groupby默认按Company排序,和外层顺序统一 df_3_inner = df_3.groupby(['Company'])['Units_sold'].sum().reset_index() fig, ax = plt.subplots(figsize=(9,6)) # 定义公司对应的深浅配色 company_colors = { 'Microsoft': {'inner': '#DB2018', 'outer': '#EA6727'}, 'Nintendo': {'inner': '#56B45B', 'outer': '#83C143'}, 'Sony': {'inner': '#156EAF', 'outer': '#5599CC'} } # 生成外层颜色列表:根据每个控制台所属公司匹配对应浅色 outer_colors = [company_colors[comp]['outer'] for comp in df_3_outer['Company']] # 生成内层颜色列表:按groupby的Company顺序匹配深色 inner_colors = [company_colors[comp]['inner'] for comp in df_3_inner['Company']] size = 0.8 r = 2 # 绘制外层环 ax.pie(df_3_outer['Units_sold'], labels=df_3_outer.Console, radius=r, colors=outer_colors, wedgeprops=dict(width=size, edgecolor='w'), textprops={'fontsize': 9}) # 绘制内层饼 ax.pie(df_3_inner.Units_sold, labels=df_3_inner.Company, radius=r-size, colors=inner_colors, labeldistance=0.6, textprops=dict(color="w", fontsize=15), wedgeprops=dict(edgecolor='w')) # 保证饼图为正圆形 ax.set_aspect('equal') plt.show()
3. 关键修改说明
- 顺序一致性:外层通过
sort_values('Company')确保同一公司的控制台连续排列,groupby('Company')默认对公司名称排序,因此内外层分段顺序完全对应。 - 配色映射:通过字典
company_colors为每个公司绑定深浅两种颜色,外层颜色列表根据控制台所属公司动态生成,确保同一公司的外层环与内层饼颜色风格统一,匹配目标图配色逻辑。 - 细节优化:添加
ax.set_aspect('equal')保证饼图为正圆,调整外层标签字体大小避免重叠。
内容的提问来源于stack exchange,提问作者Jee Bluetru
相关产品推荐
相关产品推荐

