【问题标题】:Plotly.Express + Pandas multi-index columnPlotly.Express + Pandas 多索引列
【发布时间】:2021-12-12 01:18:24
【问题描述】:

我对 Pandas 和 Plotly 比较陌生。我将直接向 MWE 提出我想要做什么的问题:

import pandas
import plotly.express as px

df = pandas.DataFrame(
    {
        'n': [1,1,1,1,2,2,2,3,3,3,4,4],
        'x': [0,0,0,0,1,1,1,2,2,2,3,3],
        'y': [1,2,1,1,2,3,3,3,4,3,4,5],
    }
)

mean_df = df.groupby(by=['n']).agg(['mean','std'])

fig = px.scatter(
    mean_df,
    x = ('x','mean'),
    y = ('y','mean'),
    error_y = ('y','std'),
)
fig.show()

这段代码没有做我想做的事。 mean_df 数据框如下所示:

     x              y          
  mean  std      mean       std
n                              
1    0  0.0  1.250000  0.500000
2    1  0.0  2.666667  0.577350
3    2  0.0  3.333333  0.577350
4    3  0.0  4.500000  0.707107

我想使用plotly.express 绘制x_meany_mean,误差线在y 中。当数据框中有子列时,我不确定如何执行此操作...

经过一番研究,我发现mean_df.columns = [' '.join(col).strip() for col in mean_df.columns.values] 将之前的数据帧转换为

   x mean  x std    y mean     y std
n                                   
1       0    0.0  1.250000  0.500000
2       1    0.0  2.666667  0.577350
3       2    0.0  3.333333  0.577350
4       3    0.0  4.500000  0.707107

所以我现在可以做

fig = px.scatter(
    mean_df,
    x = 'x mean',
    y = 'y mean',
    error_y = 'y std',
)

获得想要的结果。然而,尽管这正是我想做的,但感觉不像是要走的路……

【问题讨论】:

    标签: python pandas plotly


    【解决方案1】:

    与您的研究类似,将多级列展平。您可以使用索引切片。这确实使 mean_df 保持不变。

    下面的进一步更新。 Plotly Express 被设计为一个简单的 API。这是一个典型的用例,用于简化/构造数据框,将 x、y、颜色、hover_name 等 的概念作为字符串寻址的列。在使用多索引列的情况下,可以传递 seriesarray。下面展示了这两种变体。

    import pandas
    import plotly.express as px
    
    df = pandas.DataFrame(
        {
            'n': [1,1,1,1,2,2,2,3,3,3,4,4],
            'x': [0,0,0,0,1,1,1,2,2,2,3,3],
            'y': [1,2,1,1,2,3,3,3,4,3,4,5],
        }
    )
    
    mean_df = df.groupby(by=['n']).agg(['mean','std'])
    
    fig = px.scatter(
        mean_df.loc[:,pd.IndexSlice[:,"mean"]].droplevel(1,1),
        x = "x",
        y = "y",
    )
    fig
    
    

    使用多个 1 级键

    fig = px.scatter(
        mean_df.loc[:,pd.IndexSlice[:,"mean"]].droplevel(1,1),
        x = "x",
        y = "y",
        error_y = mean_df.loc[:,("y","std")].values
    )
    fig.show()
    px.scatter(
        x = mean_df.loc[:,("x","mean")],
        y = mean_df.loc[:,("y","mean")],
        error_y = mean_df.loc[:,("y","std")]
    )
    

    【讨论】:

    • 感谢您的回答。我会投票赞成我在问题中发布的内容。但是,我正在寻找一种不会删除列的解决方案,因为我希望 std 也可以绘制。抱歉,我会更新我的问题以反映这一点。
    • 已更新以涵盖您的问题修正。恕我直言,保持简单是件好事,因此如果存在字符串无法引用的列,请改为传递序列或数组
    猜你喜欢
    • 2017-03-04
    • 2020-08-31
    • 2014-07-10
    • 1970-01-01
    • 2021-12-17
    • 2018-10-12
    • 2018-08-18
    • 2020-11-16
    相关资源
    最近更新 更多