Plot multiple bar plots with three groups while dividing two columns

Viewed 157

I have this dummy df:

data = {'numerator_en':[11, 113, 53],
             'denominator_en':[91, 982, 298],
             'numerator_fr':[6, 232, 58],
             'denominator_fr':[63, 1278, 389],
             'numerator_th':[14, 652, 231],
             'denominator_th':[416, 3835, 1437],
             }

dummy_df = pd.DataFrame(data, index = ['numeric', 'text', 'both'])

Which looks like that: enter image description here

The goal is create such a plot: enter image description here

Note that english, french and thai should just have different colors - nothing fancy as in the image.

Hereby the y axis equals numerator_xx / denominator_xx for all languages divided into numeric, text and both.
For instance, numeric would be row numeric: numerator_en/denominator_en and numerator_fr/denominator_fr and so on...

English = _en French = _fr Thai = _th

2 Answers

Try creating a MultiIndex with str.split then divide numerator by denominator:

dummy_df.columns = dummy_df.columns.str.split('_', expand=True)
dummy_df = dummy_df['numerator'] / dummy_df['denominator']

dummy_df:

               en        fr        th
both     0.177852  0.149100  0.160752
numeric  0.120879  0.095238  0.033654
text     0.115071  0.181534  0.170013

Then plot as normal:

dummy_df.plot(kind='bar', rot=0)
plt.show()

plot


Complete Working Example:

import pandas as pd
from matplotlib import pyplot as plt

data = {'numerator_en': [11, 113, 53],
        'denominator_en': [91, 982, 298],
        'numerator_fr': [6, 232, 58],
        'denominator_fr': [63, 1278, 389],
        'numerator_th': [14, 652, 231],
        'denominator_th': [416, 3835, 1437]}

dummy_df = pd.DataFrame(data, index=['numeric', 'text', 'both'])

dummy_df.columns = dummy_df.columns.str.split('_', expand=True)
dummy_df = dummy_df['numerator'] / dummy_df['denominator']

dummy_df.plot(kind='bar', rot=0)
plt.show()

You can use groupby with axis=1 to make groups based on en/fr/th. Then you can evaluate the numerator/denominator for each group. Finally, you can use .plot(kind ='bar') to plot the bar graph.

(
    df.groupby(df.columns.map(lambda x: x.split('_')[1]), axis=1)
    .apply(lambda x: x.iloc[:, 0].div(x.iloc[:, 1]))
    .plot(kind='bar')
)

OUTPUT:

enter image description here

Related