1

how to plot multiple categories with different data lengths on the same bar chart in python?

Here is my code:

import pandas as pd
import matplotlib.pyplot as plt

Type_X = [200000, 150000]
Type_Y = [168000, 120000]
Comb = [192000]

Cat = ['With Time Constraints', 'With Production Constraints']
Cat2 = ['Optimised Combination of Devices']

df = pd.DataFrame({'Type X': Type_X,
                   'Type Y': Type_Y,}, index=Cat)

df2 = pd.DataFrame({'Comb' : Comb}, index=Cat2)

print(df)
print(df2)

ax = plt.subplots()
df.plot.barh(figsize = (15, 8), color={"Type X": "lightblue", "Type Y": "purple"})
df2.plot.barh(figsize = (15, 8), color={'Comb' : 'green'})


#annotate bars in bar plot
for container in ax.containers:
    ax.bar_label(container)
    
plt.title('SEC Weekly Profits of Devices under different Constraints', fontdict = {'fontsize': 20,
                                                         'fontweight': 'bold',
                                                         'color': 'black',
                                                         'verticalalignment': 'baseline',
                                                         'horizontalalignment': 'center'})

# export the file
# plt.savefig("SEC_Weekly_Profit_Cons", dpi = 300)


# Hide the right and top spines
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)

# plot show
plt.show()    

Here is the kind of chart I expect to see: enter image description here

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
Seun Alabi
  • 13
  • 2

1 Answers1

0
import pandas as pd

df1 = pd.DataFrame({'Type X': Type_X, 'Type Y': Type_Y,}, index=Cat)
df2 = pd.DataFrame({'Comb' : Comb}, index=Cat2)

# combined dataframe
df = pd.concat([df1, df2], axis=1)

# color dict
color = {'Type X': 'lightblue', 'Type Y': 'purple', 'Comb': 'green'}

# plot
ax = df.plot(kind='barh', color=color, figsize=(9, 5))

# annotate bars in bar plot
for c in ax.containers:
    ax.bar_label(c, fmt=lambda w: f'{round(w):,}' if w > 0 else '')
    
 # Hide the right and top spines
ax.spines[['top','right', 'bottom']].set_visible(False)

# relocate the legend
ax.legend(loc='lower center', bbox_to_anchor=(0.5, -0.2), frameon=False, ncols=3)

# remove the tick marks
plt.tick_params( axis='x', which='both', bottom=False)

enter image description here

df

                                    Type X    Type Y      Comb
With Time Constraints             200000.0  168000.0       NaN
With Production Constraints       150000.0  120000.0       NaN
Optimised Combination of Devices       NaN       NaN  192000.0

For matplotlib < v3.7.0

  • labels= instead of fmt= should be used.
for c in ax.containers:
    labels = [f'{round(w):,}' if (w := v.get_width()) > 0 else '' for v in c]
    ax.bar_label(c, labels=labels)
Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158