Search code examples
pandasmatplotlibgroup-by

Pandas `yerr` after `groupby` generates "ConversionError"


I am trying to use pandas.plot(type=bar) to plot a bar with errors. I have some variables for each sample, each sample belonging to a group. Toy example:

df=pd.DataFrame({
    'U':   [ 1, 2, 3, 4 ], 
    'V':   [ 5, 6, 7, 8 ], 
    'grp': [ 1, 1, 2, 2 ]     })

I have created mean and std for each group as follows:

uv_agg = df.groupby('grp').agg([mean, std])

The resulting table has format

       U           V 
       mean  std   mean  std
grp
1
2

I can plot bars using

uv_agg.plot( kind='bar', y=('U','mean') )  # works!

but when I try error bars with

uv_agg.plot( kind='bar', y=('U','mean'), yerr=('U','std') )

I get

ConversionError: Failed to convert value(s) to axis units: array(['U', 'std'], dtype='<U6')

I have tried stepping through the plot code but can't get it to work.


Solution

  • The parameter y takes "label, position or list of label, positions" which is why y=('U','mean') works. However, the parameter yerr takes "DataFrame, Series, array-like, dict and str" so (for example) you can use uv_agg['U']['std'] :

    import pandas as pd
    import matplotlib.pyplot as plt
    import numpy as np
    
    df = pd.DataFrame({'U': [1, 2, 3, 4],
                       'V': [5, 6, 7, 8],
                       'grp': [1, 1, 2, 2]
                       })
    
    uv_agg = df.groupby('grp').agg([np.mean, np.std])
    uv_agg.plot(kind='bar', y=('U', 'mean'), yerr=uv_agg['U']['std'], capsize=4, rot=0)
    plt.show()
    

    error bars

    You can find more in Panda's plotting docs and in plotting with error bars.