Reputation: 125
In the plot below, the threshold bars for the same year are not side by side:
I would like to have a plot like this below:
my_df = pd.DataFrame(data={'Year': \['2017','2018','2019','2019','2019','2019','2020','2020'\],
'Threshold':\[96, 91, 20.59, 47.37, 78.12, 10.00, 15.00 ,91\],
'Fee' : \["No","No", "20%", "20%", "5%", "20%", "20%", "No"\]})
palette={"No": "g","20%": "y", "5%": "r"}
fig,ax = plt.subplots()
fig.set_size_inches(10,8)
g = sns.barplot(x=my_df.index, y="Threshold",hue = 'Fee', palette = palette, data=my_df, ci=None)
g.set(xticklabels=my_df\['Year'\])
for p in ax.patches:
ax.annotate("%.2f" % p.get_height(), (p.get_x() + p.get_width() / 2, p.get_height()),
ha='center', va='center', fontsize=11, color='black', xytext=(0, 10),
textcoords='offset points',fontweight='bold')][3]][3]
Upvotes: 0
Views: 1325
Reputation: 40667
When you are diverging from the kind of plots that seaborn was designed for, you are better off relying on matplotlib directly rather than trying to bend seaborn to your will
my_df = pd.DataFrame(data={'Year': ['2017','2018','2019','2019','2019','2019','2020','2020'],
'Threshold':[96, 91, 20.59, 47.37, 78.12, 10.00, 15.00 ,91],
'Fee' : ["No","No", "20%", "20%", "5%", "20%", "20%", "No"]})
palette={"No": "g","20%": "y", "5%": "r"}
temp_df = my_df.sort_values(by=['Year','Fee'])
years = temp_df['Year'].unique()
max_bars = temp_df.groupby('Year').size().max()
width = .8/max_bars
fig, ax = plt.subplots()
for i,(year,yearly_df) in enumerate(temp_df.groupby('Year')):
N_bars = len(yearly_df)
offsets = np.linspace(0, (N_bars-1)*width, N_bars)
offsets -= offsets.mean()
a = ax.bar(i+offsets, yearly_df['Threshold'], width=width, color=yearly_df['Fee'].replace(palette))
ax.set_xticks(np.arange(len(years)))
ax.set_xticklabels(years)
for p in ax.patches:
ax.annotate("%.2f" % p.get_height(), (p.get_x() + p.get_width() / 2, p.get_height()),
ha='center', va='center', fontsize=11, color='black', xytext=(0, 10),
textcoords='offset points',fontweight='bold')
Upvotes: 1