I have a dataframe with a categorical column and a column of float values and would like to visualise the sum of the floats by categorical group as a fraction of total (e.g. 20% vs 80%). In addition, I would like to visualise the uncertainty, i.e. plot the confidence interval around the point estimates.
Here is a stylised example:
import pandas as pd
df = pd.DataFrame(data={
'flag':[True, False, True, True, True, False, True, False, True, True, True, True],
'revenue': [1,2,3,4,5,6,7,8,9,10,11,12]
})
print(df.groupby('flag').revenue.sum()/df.revenue.sum())
flag
False 0.205128
True 0.794872
Name: revenue, dtype: float64
I tried to specify the estimator in the seaborn barplot function and got this Seaborn barplot output:
import seaborn as sns
sns.barplot(data=df, x='flag', y='revenue', estimator=lambda x: np.sum(x)/df.revenue.sum())
The problem is that seaborn allows the confidence interval of the bars to extend beyond 100%, i.e. to more than the total (while it should be capped at 100%).
Here is a quick-and-dirty code sample of bootstrapping the confidence intervals properly:
def bootstrap_ratio(df):
df_bs = df.sample(n=len(df), replace=True)
return df_bs.groupby('flag').revenue.sum()/df_bs.revenue.sum()
N = 1000 # bootstrap samples
pd.concat([bootstrap_ratio(df) for i in range(N)], axis=1).quantile([0.05, 0.95], axis=1)
False True
0.05 0.052912 0.575636
0.95 0.427810 0.973333
In this case, the 90% confidence interval of flag==True is [58%, 97%], with the upper edge not more than 100%.
How would I get seaborn to do this? Or at least how could I specify confidence interval values for seaborn to plot (instead of compute)?