3
$\begingroup$

Can you please help me add error bars to my graph?

This is the csv:

run,testcase,algorithm,group,avg_weightedcost,std_weight
1,1,QI,0,20007037.36,0
2,1,Q2,0,60000000,3.76E-09
3,1,Q4,0,181801581.2,13353630.74
4,1,Q3,0,585605657.3,54852458.59
6,1,QI,1,10003518.68,0
7,1,Q2,1,292802828.7,2.00E+01
8,1,Q4,1,90900790.6,13353630.74
9,1,Q3,1,292802828.7,27426229.3

This is the code and graph generated:

g = sns.barplot(y="algorithm", x="avg_weightedcost", hue="group", 
capsize=.2, data=df)

enter image description here

This is how I tried to add the error bar:

g = sns.barplot(y="algorithm", x="avg_weightedcost", hue="group", 
xerr="std_weight", capsize=.2, data=df)

This is the error:

ValueError: err must be [ scalar | N, Nx1 or 2xN array-like ]

Modified:

csv file:

run,testcase,algorithm,group,avg_weightedcost,std_weight,avg,err
1,1,QI,0.00,20007037.36,0.00,100.00,5.00
2,1,Q2,0.00,60000000.00,0.00,50.00,20.00
3,1,Q4,0.00,181801581.20,13353630.74,50.00,10.00
4,1,Q3,0.00,585605657.30,54852458.59,20.00,1.00
6,1,QI,1.00,10003518.68,0.00,20.00,20.00
7,1,Q2,1.00,292802828.65,20.00,30.00,10.00
8,1,Q4,1.00,90900790.60,13353630.74,10.00,10.00
9,1,Q3,1.00,292802828.65,27426229.30,50.00,20.00

code:

g = sns.barplot(x=data2['avg_weightedcost'], y=data2['algorithm'], 
hue=data2['group']) 

g.errorbar(x=data2['avg_weightedcost'], y=data2['algorithm'], 
xerr=data2['std_weight'], ecolor='red', linewidth=0, capsize=15) 

Error:

ValueError: could not convert string to float: 'Q3'
$\endgroup$
2
  • $\begingroup$ According to the docs you can use factorplots when you have cats, seaborn.pydata.org/generated/seaborn.barplot.html $\endgroup$
    – Aditya
    May 18, 2018 at 16:40
  • $\begingroup$ I tried g = sns.factorplot(y="algorithm", x="avg_weightedcost", hue="group", col="testcase", data=df2, kind="bar", size=7, aspect=1) but i still cannot get the error bar working $\endgroup$
    – MTA
    May 18, 2018 at 16:41

4 Answers 4

4
$\begingroup$

Try this:

g = sns.barplot(y="algorithm", x="avg_weightedcost", hue="group", 
    xerr=df[std_weight]*1, capsize=.2, data=df)

Hope it helps

$\endgroup$
2
3
$\begingroup$

I found this question when trying to find a way to add my own precalculated, custom error bars (standard deviations) to a Seaborn barplot with grouped values. I finally managed to find a workaround... The idea is to duplicate the observations drawing from a normal distribution with the desired mean and standard deviation. Then, the built-in "ci" option in sns.barplot does the rest. Not the cleanest solution... but it does the trick (at least for small datasets). An example:

import numpy as np
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt

dfBarPlot = pd.read_csv('my_precalculated_values.csv')
#duplicate observations to get good std bars
dfCopy = dfBarPlot.copy()
duplicates = 30 # increase this number to increase precision
for index, row in dfBarPlot.iterrows():
    for times in range(duplicates):
        new_row = row.copy()
        new_row['Y'] = np.random.normal(row['Y'],row['precomputed_std']) 
        dfCopy = dfCopy.append(new_row, ignore_index=True)

# Now Seaborn does the rest
sns.set_style("whitegrid")
fig = sns.barplot(x='X',
                  y='Y',
                  hue='Cases',
                  ci='sd',
                  data=dfCopy)

plt.legend(loc='upper right')
sns.set(rc={'figure.figsize':(8,5)})
plt.show()

enter image description here

$\endgroup$
1
  • $\begingroup$ wow, what a crazy hack! Thanks $\endgroup$
    – PascalIv
    Aug 13, 2020 at 13:06
1
$\begingroup$

Update 2020-01-15

The barplot_err function is now available as part of the hhpy package

Disclaimer: I am the creator of hhpy

import hhpy.plotting as hpt
import pandas as pd

df = pd.read_csv('test.csv')

fig,ax = plt.subplots(figsize=(9,9),nrows=2)
hpt.barplot_err(y="algorithm", x="avg_weightedcost", xerr="std_weight", hue="group", 
capsize=.2, data=df, ax=ax[0])
barplot_err(x="algorithm", y="avg_weightedcost", yerr="std_weight", hue="group", 
capsize=.2, data=df, ax=ax[1])
plt.show()

This answer is based on 1gnaci0 7's. But you don't need to create 30 duplicates by drawing from a normal distribution. If your only goal is showing the error bars you only need 3 duplicates (x-xerr, x, x+xerr) [respective for y] and you're good to go (and most of all the bars are exact!).

So I turned it into a function that works for both x and y directions and 'only' triples the size of the initial dataframe.

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

def barplot_err(x, y, xerr=None, yerr=None, data=None, **kwargs):

    _data = []
    for _i in data.index:

        _data_i = pd.concat([data.loc[_i:_i]]*3, ignore_index=True, sort=False)
        _row = data.loc[_i]
        if xerr is not None:
            _data_i[x] = [_row[x]-_row[xerr], _row[x], _row[x]+_row[xerr]]
        if yerr is not None:
            _data_i[y] = [_row[y]-_row[yerr], _row[y], _row[y]+_row[yerr]]
        _data.append(_data_i)

    _data = pd.concat(_data, ignore_index=True, sort=False)

    _ax = sns.barplot(x=x,y=y,data=_data,ci='sd',**kwargs)

    return _ax

df = pd.read_csv('test.csv')

fig,ax = plt.subplots(figsize=(9,9),nrows=2)
barplot_err(y="algorithm", x="avg_weightedcost", xerr="std_weight", hue="group", 
capsize=.2, data=df, ax=ax[0])
barplot_err(x="algorithm", y="avg_weightedcost", yerr="std_weight", hue="group", 
capsize=.2, data=df, ax=ax[1])
plt.show()

seaborn barplot with custom error bars

$\endgroup$
0
$\begingroup$

Same idea as @1gnaci0 7 but a faster way of duplicating rows:

import numpy as np
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt

duplicates=1000
dfBarPlot = pd.read_csv('my_precalculated_values.csv')
#duplicate observations to get good std bars
dfCopy = dfBarPlot.loc[dfBarPlot.index.repeat(duplicates)].copy()
dfCopy['Y'] = np.random.normal(dfCopy['Y'].values,dfCopy['precomputed_std'].values)

fig = sns.barplot(x='X', y='Y', hue='Cases', ci='sd', data=dfCopy)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.