I am trying to plot grouped bar with a line graph on it using seaborn.
So far I have achieved to plt the graph. However, the bars are getting overlapped and also need some help to align the text.
DataFrame:
df_long = pd.DataFrame({
'group': [ 9, 10, 11, 12, 13, 14, 15, 16, 17,18, 19, 20, 21, 22, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22],
'status': ['1st hour', '1st hour', '1st hour', '1st hour', '1st hour',
'1st hour', '1st hour', '1st hour', '1st hour', '1st hour',
'1st hour', '1st hour', '1st hour', '1st hour', '2nd hour',
'2nd hour', '2nd hour', '2nd hour', '2nd hour', '2nd hour',
'2nd hour', '2nd hour', '2nd hour', '2nd hour', '2nd hour',
'2nd hour', '2nd hour', '2nd hour', '3rd hour', '3rd hour',
'3rd hour', '3rd hour', '3rd hour', '3rd hour', '3rd hour',
'3rd hour', '3rd hour', '3rd hour', '3rd hour', '3rd hour',
'3rd hour', '3rd hour', '4th hour', '4th hour', '4th hour',
'4th hour', '4th hour', '4th hour', '4th hour', '4th hour',
'4th hour', '4th hour', '4th hour', '4th hour', '4th hour',
'4th hour', '5th hour', '5th hour', '5th hour', '5th hour',
'5th hour', '5th hour', '5th hour', '5th hour', '5th hour',
'5th hour', '5th hour', '5th hour', '5th hour', '5th hour',
'6th hour', '6th hour', '6th hour', '6th hour', '6th hour',
'6th hour', '6th hour', '6th hour', '6th hour', '6th hour',
'6th hour', '6th hour', '6th hour', '6th hour'],
"value":
[44.88, 45.56, 46.67, 47.37, 47.74, 49.1 , 50.68, 49.64, 50.97,
48.5 , 52.69, 54.38, 49.89, 58.66, 16.14, 17.22, 15.77, 16.69,
16.22, 16.41, 15.68, 16.21, 15.54, 15.55, 14.1 , 14.08, 16.44,
12.82, 6.45, 6.13, 6.12, 5.47, 5.89, 6.13, 5.92, 6.26,
6.08, 6.38, 7.88, 5.96, 5.38, 4.73, 4.14, 3.68, 3.76,
3.62, 3.69, 3.89, 3.64, 3.84, 3.73, 6.16, 3.62, 2.91,
3.27, 3.12, 3.35, 2.47, 3.25, 2.92, 3.47, 2.77, 2.51,
2.81, 3.65, 2.98, 2.18, 1.59, 2.18, 0.58, 2.6 , 2.06,
2.55, 2.57, 2.52, 2.33, 2.84, 2.6 , 2.15, 1.71, 0.93,
0.86, 1.24, 0.92]})
Code:
import matplotlib.pyplot as plt
import seaborn as sns
fig, ax = plt.subplots(figsize=(20, 8))
g = sns.barplot(data=df_long, x='group', y='value', hue='status', ax=ax)
for bar in g.patches:
height = bar.get_height()
ax.text(bar.get_x() + bar.get_width()/3, 0.7 * height, int(height),
ha='center', va='center', color='white')
def change_width(ax, new_value) :
for patch in ax.patches :
current_width = patch.get_width()
diff = current_width - new_value
# we change the bar width
patch.set_width(new_value)
# we recenter the bar
patch.set_x(patch.get_x() + diff * .5)
change_width(ax, .30)
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))
plt.show()
Output:
- I wanted to alight the text and organise these bars for each group.
- I want to plot a line graph over these bars by taking the sum of "value" column for each group.
Code:
ax2 = ax.twinx()
color = 'tab:red'
ax2.set_ylabel('AverageEfficiency', fontsize=16)
freq = df_long.groupby('group').agg({"value": "sum"})
ax2 = sns.lineplot(x=freq.index.values, y=freq.value.values)
ax2.tick_params(color=color)
But this din't work well.