2

need some assistance here. I need to align each subgroup to their respective outer groups (which are 25% each), any ideas how to do this?

This is what I have got so far

data = {'Accenture': [3,2,2],
        'Novo BPO': [2.67,3,2],
        'SSC': [1,1,1.5],
        'inHouse': [3,2,1.5]
        }

df = pd.DataFrame(data, columns = ['Accenture','Novo BPO','SSC','inHouse'], index=['Fluidez', '% Savings', 'Escalabilidade'])
df

# Make data: I have 4 groups and 12 subgroups - 3 for each group
group_names=['groupA', 'groupB', 'groupC', 'groupD']
group_size=[25,25,25,25]
subgroup_names=['A.1', 'A.2', 'A.3', 'B.1', 'B.2','B.3', 'C.1', 'C.2', 'C.3','D.1', 'D.2', 'D.3']
subgroup_size=[3,2,2,2.67,3,2,1,1,1.5,3,2,1.5]
 
# Create colors
a, b, c,d=[plt.cm.Blues, plt.cm.Reds, plt.cm.Greens, plt.cm.Greys]
 
# First Ring (outside)
fig, ax = plt.subplots()
ax.axis('equal')
mypie, _ = ax.pie(group_size, radius=1.3, labels=group_names, colors=[a(0.6), b(0.6), c(0.6),d(0.6)] )
plt.setp( mypie, width=0.3, edgecolor='white')
 
# Second Ring (Inside)
mypie2, _ = ax.pie(subgroup_size, radius=1.3-0.3, labels=subgroup_names, labeldistance=0.7, colors=[a(0.5), a(0.4), a(0.3), b(0.5), b(0.4),b(0.3), c(0.6), c(0.5), c(0.4), d(0.3), d(0.2),d(0.4)])
plt.setp( mypie2, width=0.4, edgecolor='white')
plt.margins(0,0)
 
# show it
plt.show()
Tom McLean
  • 5,583
  • 1
  • 11
  • 36

2 Answers2

1

You have to make clear how the values for subgroup_size and group_size relate to each other! Do the values for the subgroups describe just the ratio within each quarter? Or are there really only four outer groups in total, but their share is not 25% each and you rather want to add up the values of the subgroups to get the size of the outer groups?

# Assuming subgroup_size describes a ratio for each quarter
subgroup_size = np.array(subgroup_size).reshape(4, 3) 
subgroup_size = subgroup_size / subgroup_size.sum(axis=1, keepdims=1)
subgroup_size = subgroup_size.ravel()

two donuts, ratio

# Assuming group_size is not 1/4
group_size = np.array(subgroup_size).reshape(4, 3).sum(axis=1)

two donuts, not 25% each

scleronomic
  • 4,392
  • 1
  • 13
  • 43
0

You could create the lists directly from the information in the dataframe:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

data = {'Accenture': [3, 2, 2],
        'Novo BPO': [2.67, 3, 2],
        'SSC': [1, 1, 1.5],
        'inHouse': [3, 2, 1.5]
        }

df = pd.DataFrame(data, columns=['Accenture', 'Novo BPO', 'SSC', 'inHouse'],
                  index=['Fluidez', '% Savings', 'Escalabilidade'])

group_names = df.columns
group_size = [100 / len(group_names)] * len(group_names)
subgroup_names = ['A.1', 'A.2', 'A.3', 'B.1', 'B.2', 'B.3', 'C.1', 'C.2', 'C.3', 'D.1', 'D.2', 'D.3']

# Make data: I have 4 groups and 12 subgroups - 3 for each group
subgroup_size = []
for group, size in zip(df.columns, group_size):
    subgroup_sum = df[group].sum()
    subgroup_size += [subgr / subgroup_sum * size for subgr in df[group]]

# Create colors
a, b, c, d = [plt.cm.Blues, plt.cm.Reds, plt.cm.Greens, plt.cm.Greys]

# First Ring (outside)
fig, ax = plt.subplots()
ax.axis('equal')
mypie, _ = ax.pie(group_size, radius=1.3, labels=group_names, colors=[a(0.6), b(0.6), c(0.6), d(0.6)])
plt.setp(mypie, width=0.3, edgecolor='white')

# Second Ring (Inside)
mypie2, _ = ax.pie(subgroup_size, radius=1.3 - 0.3, labels=subgroup_names, labeldistance=0.7,
                   colors=[a(0.5), a(0.4), a(0.3), b(0.5), b(0.4), b(0.3), c(0.6), c(0.5), c(0.4), d(0.3), d(0.2),
                           d(0.4)])
plt.setp(mypie2, width=0.4, edgecolor='white')
plt.margins(0, 0)

plt.show()

aligned pie chart donuts

JohanC
  • 71,591
  • 8
  • 33
  • 66