I have a Pandas dataframe that has a couple of group columns like below.
gr1 grp2 variables lb m ub
A A1 V1 1.00 1.50 2.5
A A2 V2 1.50 2.50 3.5
B A1 V1 3.50 14.50 30.5
B A2 V2 0.25 0.75 1.0
I am trying to get a separate sub-barplot for each variable in variables
using FacetGrid
. I am trying to build to the final plot that I need which looks like the below.
This is what I have so far.
g = sns.FacetGrid(df, col="variables", hue="grp1")
g.map(sns.barplot, 'grp2', 'm', order=times)
But unfortunately this is stacking all my datapoints.
How should I go about doing this with Seaborn
?
UPDATE: The following code largely does what I'm after but currently does not display yerr
.
g = sns.factorplot(x="Grp2", y="m", hue="Grp1", col="variables", data=df, kind="bar", size=4, aspect=.7, sharey=False)
How can I incorporate the lb
and ub
as error bars on the factorplot?
Before we start let me mention that matplotlib requires the errors to be relative to the data, not absolute boundaries. We would hence modify the dataframe to account for that by subtracting the respective columns.
Now there are two solutions, which are essentially the same. Let's start with a solution which does not use seaborn, but the pandas plotting wrapper (the reason will become clear later).
Not using Seaborn
Pandas allows to plot grouped barplots by using dataframes where each column belongs to or constitutes one group. The steps to take are therefore
variables
.groupby
the dateframe byvariables
grp1
as columns and them
as values. Do the same for the two error columns.The code would then look like:
using Seaborn
Seaborn factorplot does not allow for custom errorbars. One would therefore need to use the
FaceGrid
approach. In order not to have the bars stacked, one would put thehue
argument in themap
call. The following is thus the equivalent of thesns.factorplot
call from the question.Now the problem is, we cannot get the errorbars into the barplot from the outside or more importantly, we cannot give the errors for a grouped barchart to
seaborn.barplot
. For a non grouped barplot one would be able to supply the error via theyerr
argument, which is passed onto the matplotlibplt.bar
plot. This concept is shown in this question. However, sinceseaborn.barplot
callsplt.bar
several times, once for eachhue
, the errors in each call would be the same (or their dimension wouldn't match).The only option I see is hence to use a
FacetGrid
and map exactly the same function as used above to it. This somehow renders the use of seaborn obsolete, but for completeness, here is theFacetGrid
solution.