【问题标题】:Plotting the mean of multiple columns including standard deviation绘制多列的平均值,包括标准偏差
【发布时间】:2021-12-11 22:42:25
【问题描述】:

我有一个包含 8 列和多行的数据集。这些列包含 2 个不同条件下不同变量(总共 6 个)的测量值,每个包含 4 列,其中包含针对特定条件的重复测量值。

使用 Searborn,我想生成一个条形图,显示每 4 列的平均值和标准差,按索引键(即测量变量)分组。数据框结构如下:

np.random.seed(10)
df = pd.DataFrame({
    'S1_1':np.random.randn(6),
    'S1_2':np.random.randn(6),
    'S1_3':np.random.randn(6),
    'S1_4':np.random.randn(6),
    'S2_1':np.random.randn(6),
    'S2_2':np.random.randn(6),
    'S2_3':np.random.randn(6),
    'S2_4':np.random.randn(6),
    },index= ['var1','var2','var3','var4','var5','var6'])

我如何传递给 seaborn,我只想要 2 个小节,前 4 列 1 个,第二个列 1 个。每个条形显示 4 列中的平均值(和标准偏差或其他一些分散度量)。

我正在考虑使用多索引,添加第二列级别以将列分组为 2 个条件,

df.columns = pd.MultiIndex.from_arrays([['Condition 1'] * 4 + ['Condition 2'] * 4,df.columns])

但我不知道应该将什么传递给 Seaborn 以生成我想要的情节。

如果有人能指出我正确的方向,那将是一个很大的帮助!

【问题讨论】:

    标签: python pandas matplotlib seaborn bar-chart


    【解决方案1】:

    根据评论更新

    • 绘图就是为绘图 API 重塑数据框
    # still create the groups
    l = df.columns
    n = 4
    groups = [l[i:i+n] for i in range(0, len(l), n)]
    num_gps = len(groups)
    
    # stack each group and add an id column
    data_list = list()
    for group in groups:
        id_ = group[0][1]
        data = df[group].copy().T
        data['id_'] = id_
        data_list.append(data)
        
    df2 = pd.concat(data_list, axis=0).reset_index()
    df2.rename({'index': 'sample'}, axis=1, inplace=True)
    
    # melt df2 into a long form
    dfm = df2.melt(id_vars=['sample', 'id_'])
    
    # plot
    p = sns.catplot(kind='bar', data=dfm, x='variable', y='value', hue='id_', ci='sd', aspect=3)
    

    df2.head()

      sample    YAL001C    YAL002W   YAL004W   YAL005C   YAL007C   YAL008W    YAL011W   YAL012W    YAL013W   YAL014C id_
    0   S2_1 -13.062716  -8.084685  2.360795 -0.740357  3.086768 -0.117259  -5.678183  2.527573 -17.326287 -1.319402   2
    1   S2_2  -5.431474 -12.676807  0.070569 -4.214761 -4.318011 -4.489010 -10.268632  0.691448 -24.189106 -2.343884   2
    2   S2_3  -9.365509 -12.281169  0.497772 -3.228236  0.212941 -2.287206 -10.250004  1.111842 -27.811564 -4.329987   2
    3   S2_4  -7.582111 -15.587219 -1.286167 -4.531494 -3.090265 -4.718281  -8.933496  2.079757 -21.580854 -2.834441   2
    4   S3_1 -12.618254 -20.010779 -2.530541 -3.203072 -2.436503 -2.922565 -15.972632  3.551605 -35.618485 -4.925495   3
    

    dfm.head()

      sample id_ variable      value
    0   S2_1   2  YAL001C -13.062716
    1   S2_2   2  YAL001C  -5.431474
    2   S2_3   2  YAL001C  -9.365509
    3   S2_4   2  YAL001C  -7.582111
    4   S3_1   3  YAL001C -12.618254
    

    绘制结果

    kind='box'

    • 箱线图可能更好地传达分布
    p = sns.catplot(kind='box', data=dfm, y='variable', x='value', hue='id_', height=12)
    


    原答案

    • 使用列表解析将列分成 4 个组
      • 这使用已发布的更全面的原始数据。可以在revision 4找到
    • 创建带有子图的图形并将每个组从axes 压缩到ax
    • 使用每个groupdf 中选择data 并用.T 转置数据。
    • 使用sns.barplot默认estimator为均值,所以条形长度为均值,设置ci='sd'则置信区间为标准差。
      • sns.barplot(data=data, ci='sd', ax=ax) 可以轻松替换为 sns.boxplot(data=data, ax=ax)
    import seaborn as sns
    
    # using the first comma separated data that was posted, create groups of 4
    l = df.columns
    n = 4  # chunk size for groups
    groups = [l[i:i+n] for i in range(0, len(l), n)]
    num_gps = len(groups)
    
    # plot
    fig, axes = plt.subplots(num_gps, 1, figsize=(12, 6*num_gps))
    
    for ax, group in zip(axes, groups):
        data = df[group].T
        sns.barplot(data=data, ci='sd', ax=ax)
        ax.set_title(f'{group.to_list()}')
    fig.tight_layout()
    fig.savefig('test.png')
    

    data 的示例

    • 条是每列的mean,行是standard deviation
           YAL001C    YAL002W   YAL004W   YAL005C   YAL007C   YAL008W    YAL011W   YAL012W    YAL013W   YAL014C
    S8_1 -1.731388 -17.215712 -3.518643 -2.358103  0.418170 -1.529747 -12.630343  2.435674 -27.471971 -4.021264
    S8_2 -1.325524 -24.056632 -0.984390 -2.119338 -1.770665 -1.447103 -10.618954  2.156420 -30.362998 -4.735058
    S8_3 -2.024020 -29.094027 -6.146880 -2.101090 -0.732322 -2.773949 -12.642857 -0.009749 -28.486835 -4.783863
    S8_4  2.541671 -13.599049 -2.688125 -2.329332 -0.694555 -2.820627  -8.498677  3.321018 -31.741916 -2.104281
    

    绘制结果

    【讨论】:

    • 非常感谢特伦顿。这很棒!为更改数据而道歉。想我会简化一点。
    • 理想情况下,我想将 8 个子图组合成 1 个变量分组的图。我意识到,从我提出的问题中并不清楚这一点。但这非常接近,我会看看我是否可以从这里弄清楚。再次感谢!
    • 太棒了!这正是我想要的。感谢您花时间向我解释这一点。一开始是一个陡峭的学习曲线。
    • @JohanvH 不客气。我很高兴这对你有用。
    猜你喜欢
    • 2020-01-11
    • 2017-08-30
    • 1970-01-01
    • 2021-03-06
    • 2015-03-05
    • 2015-03-04
    • 2021-05-22
    • 1970-01-01
    • 2018-11-04
    相关资源
    最近更新 更多