Seaborn confidence intervals for fraction of total

Viewed 134

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

0 Answers
Related