seaborn:如何在分组的条形图上添加误差线

时间:2017-02-03 04:56:44

标签: python python-2.7 pandas matplotlib seaborn

我的数据框 df 有四列:CandidateSample_SetValues和{ {1}}。例如,Error列有三个唯一条目:Candidate我们有三个样本集,因此[X, Y, Z]也有三个唯一值:Sample_Set。 df大致看起来像这样。

[1,2,3]

我正在使用通过Candidate,Sample_Set,Values,Error X,1,20,50 Y,1,10,50 Z,1,10,50 X,2,200,30 Y,2,101,30 Z,2,99,30 X,3,1999,10 Y,3,998,10 Z,3,1003,10 x="Candidate"y="Values"创建一个分组的条形图。一切顺利,直到我尝试使用名为hue="Sample_Set"的列下的值沿y轴添加错误栏。我使用以下代码。

Error

如何合并错误?

我很欣赏这项任务的解决方案或更优雅的方法。

3 个答案:

答案 0 :(得分:4)

正如@ResMar在评论中指出的那样,seaborn中似乎没有内置功能可以轻松设置单个错误栏。

如果您更关心结果而不是达到目标的方式,那么以下(不那么优雅)的解决方案可能会有所帮助,它建立在matplotlib.pyplot.bar之上。 seaborn导入仅用于获得相同的风格。

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

def grouped_barplot(df, cat,subcat, val , err):
    u = df[cat].unique()
    x = np.arange(len(u))
    subx = df[subcat].unique()
    offsets = (np.arange(len(subx))-np.arange(len(subx)).mean())/(len(subx)+1.)
    width= np.diff(offsets).mean()
    for i,gr in enumerate(subx):
        dfg = df[df[subcat] == gr]
        plt.bar(x+offsets[i], dfg[val].values, width=width, 
                label="{} {}".format(subcat, gr), yerr=dfg[err].values)
    plt.xlabel(cat)
    plt.ylabel(val)
    plt.xticks(x, u)
    plt.legend()
    plt.show()

df = pd.read_csv("candf.txt")
print df

cat = "Candidate"
subcat = "Sample_Set"
val = "Values"
err = "Error"
grouped_barplot(df, cat, subcat, val, err )

enter image description here

请注意,只需反转类别和子类别

即可
cat = "Sample_Set"
subcat = "Candidate"

您可以获得不同的分组:

enter image description here

答案 1 :(得分:0)

您可以使用pandas绘制功能来接近您需要的内容:see this answer

bars = data.groupby("Candidate").plot(kind='bar',x="Sample_Set", y= "Values", yerr=data['Error'])

这并不是你想要的,但非常接近。不幸的是,ggplot2 for python目前无法正确呈现错误栏。就个人而言,在这种情况下我会诉诸R ggplot2

data <- read.csv("~/repos/tmp/test.csv")
data
library(ggplot2)
ggplot(data, aes(x=Candidate, y=Values, fill=factor(Sample_Set))) + 
  geom_bar(position=position_dodge(), stat="identity") +
  geom_errorbar(aes(ymin=Values-Error, ymax=Values+Error), width=.1, position=position_dodge(.9)) 

答案 2 :(得分:0)

我建议从 patches 属性中提取位置坐标,然后绘制误差线。

ax = sns.barplot(data=df, x="Candidate", y="Values", hue="Sample_Set")
x_coords = [p.get_x() + 0.5*p.get_width() for p in ax.patches]
y_coords = [p.get_height() for p in ax.patches]
plt.errorbar(x=x_coords, y=y_coords, yerr=df["Error"], fmt="none", c= "k")