我的pandas数据框 df
有四列:Candidate
,Sample_Set
,Values
和{ {1}}。例如,Error
列有三个唯一条目:Candidate
我们有三个样本集,因此[X, Y, Z]
也有三个唯一值:Sample_Set
。 df大致看起来像这样。
[1,2,3]
我正在使用seaborn通过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
如何合并错误?
我很欣赏这项任务的解决方案或更优雅的方法。
答案 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 )
请注意,只需反转类别和子类别
即可cat = "Sample_Set"
subcat = "Candidate"
您可以获得不同的分组:
答案 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")