4

I have the following dataframe that represents the total of employees per department/area in each region.

               Finance   HR   IT  Marketing  Medical  Operations  Sales
Business Unit                                                          
Cardiology           0    2    1          0        3           0      0
Genetics             1    4    3          1        3           1      1
Imaging             34   74   70         38       68          18     33
Labs                63  130  131         66      130          32     68
Pathology            2    5   10          4        8           3      6

Using this dataframe, I generated bellow graph using this code:

#Plot the graph
fig, ax = plt.subplots(1, 5, figsize=(30, 15), sharey = True)
iax = iter(ax.flatten())
for n, g in df.groupby('Business Unit'):
    g.loc[n, :].plot.bar(ax=next(iax),  title=f'{n}', stacked=True, legend = True, fontsize = 30)

enter image description here

As you can see, the text size of the subplot where the Business Unit is informed and also the legend size (in the top corner) is way too small. How could I increase the text of both of them?

Also, is there a way I could add in this code a way to display the % from the total in each of those columns?

Thank you so much for your help!

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Paulo Cortez
  • 609
  • 4
  • 10

1 Answers1

3
import pandas as pd

# load dataframe
data = {'Cardiology': {'Finance': 0, 'HR': 2, 'IT': 1, 'Marketing': 0, 'Medical': 3, 'Operations': 0, 'Sales': 0}, 'Genetics': {'Finance': 1, 'HR': 4, 'IT': 3, 'Marketing': 1, 'Medical': 3, 'Operations': 1, 'Sales': 1}, 'Imaging': {'Finance': 34, 'HR': 74, 'IT': 70, 'Marketing': 38, 'Medical': 68, 'Operations': 18, 'Sales': 33}, 'Labs': {'Finance': 63, 'HR': 130, 'IT': 131, 'Marketing': 66, 'Medical': 130, 'Operations': 32, 'Sales': 68}, 'Pathology': {'Finance': 2, 'HR': 5, 'IT': 10, 'Marketing': 4, 'Medical': 8, 'Operations': 3, 'Sales': 6}}
df = pd.DataFrame.from_dict(data, orient='index')

# get the total for each business unit; used to calculate percent
bu_total = df.sum(axis=1)

# get the total for each division; used to calculate percent
div_total = df.sum(axis=0)

# plot
axes = df.T.plot(kind='bar', subplots=True, layout=(1, 5), figsize=(22, 6), sharey=True, ylabel='Expenditures ($)')

# iterate through axes subplots
for ax in axes[0]:
    # title is used to get the total from bu_total
    title = ax.get_title()
    
    ax.legend(fontsize=15)
    ax.set_xticklabels(ax.get_xticklabels(), fontdict={'fontsize':24})
    ax.set_title(title, fontdict={'fontsize':24})
    ax.set_ylabel(ax.get_ylabel(), fontdict={'fontsize':24})
    
    # customized labels for % business unit total
    bu_labels = [f'{(v.get_height() / bu_total[title])*100 :.0f}%' for v in ax.containers[0]]
    
    # customized labels for % division total
    div_labels = [f'{(v.get_height() / div_total[i])*100 :.0f}%' for i, v in enumerate(ax.containers[0])]
    
    # annotate as desired: use bu_lables or div_labels
    ax.bar_label(ax.containers[0], labels=bu_labels, label_type='edge', fontsize=10)

    # pad the spacing between the number and the edge of the figure
    ax.margins(y=0.1)

enter image description here

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158