Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Seaborn:使用非对称自定义错误条按组制作条形图_Python_Matplotlib_Plot_Data Visualization_Seaborn - Fatal编程技术网

Python Seaborn:使用非对称自定义错误条按组制作条形图

Python Seaborn:使用非对称自定义错误条按组制作条形图,python,matplotlib,plot,data-visualization,seaborn,Python,Matplotlib,Plot,Data Visualization,Seaborn,我有一个Pandas数据框架,它有两个组列,如下所示 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

我有一个Pandas数据框架,它有两个组列,如下所示

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
我正在尝试使用
FacetGrid
variables
中的每个变量获取一个单独的子条形图。我正在努力构建我需要的最终情节,如下图所示

这就是我目前所拥有的

g = sns.FacetGrid(df, col="variables", hue="grp1")
g.map(sns.barplot, 'grp2', 'm', order=times)
但不幸的是,这正在堆积我所有的数据点

我应该如何使用
Seaborn

更新:下面的代码主要是我想要的,但目前没有显示
yerr

g = sns.factorplot(x="Grp2", y="m", hue="Grp1", col="variables", data=df, kind="bar", size=4, aspect=.7, sharey=False)

如何将
lb
ub
合并为factorplot上的错误条?

在开始之前,让我提到matplotlib要求错误与数据相关,而不是绝对边界。因此,我们将修改dataframe,通过减去相应的列来说明这一点

u = u"""grp1 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     7.50   14.50   20.5           
B   A2      V2     0.25   0.75    1.0
A   A2      V1     1.00   6.50    8.5           
A   A1      V2     1.50   3.50    6.5         
B   A2      V1     3.50   4.50   15.5           
B   A1      V2     8.25   12.75  13.9"""

import io
import pandas as pd

df = pd.read_csv(io.StringIO(u), delim_whitespace=True)
# errors must be relative to data (not absolute bounds)
df["lb"] = df["m"]-df["lb"]
df["ub"] = df["ub"]-df["m"]
现在有两种基本相同的解决方案。让我们从一个解决方案开始,该解决方案不使用seaborn,而是使用pandas plotting包装器(原因将在稍后明确)

不使用Seaborn Pandas允许使用数据帧绘制分组条形图,其中每列属于或构成一个组。 因此,应采取的步骤是:

  • 根据不同
    变量的数量创建多个子批次
  • groupby
    dateframe by
    variables
  • 对于每个组,创建一个数据透视框,其中
    grp1
    的值作为列,而
    m
    的值作为值。对两个错误列执行相同的操作
  • 从中应用解决方案
  • 然后,代码将如下所示:

    import io
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    
    df = pd.read_csv(io.StringIO(u), delim_whitespace=True)
    # errors must be relative to data (not absolute bounds)
    df["lb"] = df["m"]-df["lb"]
    df["ub"] = df["ub"]-df["m"]
    
    def func(x,y,h,lb,ub, **kwargs):
        data = kwargs.pop("data")
        # from https://stackoverflow.com/a/37139647/4124317
        errLo = data.pivot(index=x, columns=h, values=lb)
        errHi = data.pivot(index=x, columns=h, values=ub)
        err = []
        for col in errLo:
            err.append([errLo[col].values, errHi[col].values])
        err = np.abs(err)
        p = data.pivot(index=x, columns=h, values=y)
        p.plot(kind='bar',yerr=err,ax=plt.gca(), **kwargs)
    
    fig, axes = plt.subplots(ncols=len(df.variables.unique()))
    for ax, (name, group) in zip(axes,df.groupby("variables")):
        plt.sca(ax)
        func("grp2", "m", "grp1", "lb", "ub", data=group, color=["limegreen", "indigo"])
        plt.title(name)
    
    plt.show()
    

    使用Seaborn Seaborn FactoryPlot不允许自定义错误栏。因此,需要使用
    FaceGrid
    方法。为了不让条形图堆叠,可以将
    hue
    参数放在
    map
    调用中。因此,以下内容相当于问题的
    sns.factorplot
    调用

    g = sns.FacetGrid(data=df, col="variables", size=4, aspect=.7 ) 
    g.map(sns.barplot, "grp2", "m", "grp1", order=["A1","A2"] )
    
    现在的问题是,我们无法从外部将ErrorBar输入条形图,或者更重要的是,我们无法将分组条形图的错误提供给
    seaborn.barplot
    。对于未分组的条形图,可以通过
    yerr
    参数提供错误,该参数传递到matplotlib
    plt.bar
    绘图。这一概念如所示。但是,由于
    seaborn.barplot
    多次调用
    plt.bar
    ,每个
    hue
    调用一次,因此每次调用中的错误都是相同的(或者它们的维度不匹配)

    因此,我看到的唯一选择是使用
    FacetGrid
    ,并将上面使用的函数完全映射到它。这在某种程度上使seaborn的使用变得过时,但为了完整起见,这里是
    FaceGrid
    解决方案

    import io
    import numpy as np
    import pandas as pd
    import seaborn as sns
    import matplotlib.pyplot as plt
    
    df = pd.read_csv(io.StringIO(u), delim_whitespace=True)
    # errors must be relative to data (not absolute bounds)
    df["lb"] = df["m"]-df["lb"]
    df["ub"] = df["ub"]-df["m"]
    
    def func(x,y,h,lb,ub, **kwargs):
        data = kwargs.pop("data")
        # from https://stackoverflow.com/a/37139647/4124317
        errLo = data.pivot(index=x, columns=h, values=lb)
        errHi = data.pivot(index=x, columns=h, values=ub)
        err = []
        for col in errLo:
            err.append([errLo[col].values, errHi[col].values])
        err = np.abs(err)
        p = data.pivot(index=x, columns=h, values=y)
        p.plot(kind='bar',yerr=err,ax=plt.gca(), **kwargs)
    
    g = sns.FacetGrid(df, col="variables", size=4, aspect=.7,  ) 
    g.map_dataframe(func, "grp2", "m", "grp1", "lb", "ub" , color=["limegreen", "indigo"]) 
    g.add_legend()
    
    plt.show()
    

    非常感谢您的详细回复,我对代码做了一些修改,使其适合我的具体用例,并且工作得非常完美。