Renata Mesquita
Renata Mesquita

Reputation: 125

Seaborn barplot does not show columns side by side

In the plot below, the threshold bars for the same year are not side by side:

SNS barplot

I would like to have a plot like this below:

enter image description here

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

Answers (1)

Diziet Asahi
Diziet Asahi

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')

enter image description here

Upvotes: 1

Related Questions