代码之家  ›  专栏  ›  技术社区  ›  Pandas INC

如何使用更新优化plotly graph?

  •  0
  • Pandas INC  · 技术社区  · 5 年前

    所以,我经常使用plotly,最近开始使用updatemenus方法来添加按钮。我已经用它创建了几个图,但是我发现很难找到一个有效的方法来更新updatemenus部分中的args部分。我有一个比示例更大的数据帧,但这是相同的想法,所以我有df:

    name    unaregate   value   age
    input1  in11           2    0
    input1  in11           0    1
    input1  in11           2    2
    input1  in11           3    3
    input1  in11           1    4
    input1  in12           1    0
    input1  in12           3    1
    input1  in12           4    2
    input1  in12           2    3
    input1  in12           3    4
    input1  in13           0    0
    input1  in13           2    1
    input1  in13           4    2
    input1  in13           2    3
    input1  in13           3    4
    input2  in21           3    0
    input2  in21           4    1
    input2  in21           2    2
    input2  in21           1    3
    input2  in21           3    4
    input2  in22           4    0
    input2  in22           0    1
    input2  in22           2    2
    input2  in22           4    3
    input2  in22           0    4
    input2  in23           3    0
    input2  in23           4    1
    input2  in23           0    2
    input2  in23           4    3
    input2  in23           2    4
    input3  in31           3    0
    input3  in31           4    1
    input3  in31           2    2
    input3  in31           4    3
    input3  in31           1    4
    input3  in32           4    0
    input3  in32           0    1
    input3  in32           0    2
    input3  in32           2    3
    input3  in32           1    4
    input3  in33           2    0
    input3  in33           3    1
    input3  in33           0    2
    input3  in33           3    3
    input3  in33           4    4
    input3  in34           2    0
    input3  in34           2    1
    input3  in34           3    2
    input3  in34           4    3
    input3  in34           3    4
    

    下面是一种非常低效的方法来创建类似于以下内容的数据帧:

    df = pd.DataFrame(index=range(5),columns=range(1))
    df12 = pd.DataFrame(index=range(5),columns=range(1))
    df13 = pd.DataFrame(index=range(5),columns=range(1))
    df21 = pd.DataFrame(index=range(5),columns=range(1))
    df22 = pd.DataFrame(index=range(5),columns=range(1))
    df23 = pd.DataFrame(index=range(5),columns=range(1))
    df31 = pd.DataFrame(index=range(5),columns=range(1))
    df32 = pd.DataFrame(index=range(5),columns=range(1))
    df33 = pd.DataFrame(index=range(5),columns=range(1))
    df34 = pd.DataFrame(index=range(5),columns=range(1))
    df["name"] = "input1"
    df["unaregate"] = "in11"
    df["value"] = np.random.randint(0,5, size=len(df))
    df["age"] = range(0,len(df))
    ​
    df12["name"] = "input1"
    df12["unaregate"] = "in12"
    df12["value"] = np.random.randint(0,5, size=len(df12))
    df12["age"] = range(0,len(df12))
    ​
    df13["name"] = "input1"
    df13["unaregate"] = "in13"
    df13["value"] = np.random.randint(0,5, size=len(df13))
    df13["age"] = range(0,len(df13))
    ​
    df21["name"] = "input2"
    df21["unaregate"] = "in21"
    df21["value"] = np.random.randint(0,5, size=len(df21))
    df21["age"] = range(0,len(df21))
    ​
    df22["name"] = "input2"
    df22["unaregate"] = "in22"
    df22["value"] = np.random.randint(0,5, size=len(df22))
    df22["age"] = range(0,len(df22))
    ​
    df23["name"] = "input2"
    df23["unaregate"] = "in23"
    df23["value"] = np.random.randint(0,5, size=len(df23))
    df23["age"] = range(0,len(df23))
    ​
    df31["name"] = "input3"
    df31["unaregate"] = "in31"
    df31["value"] = np.random.randint(0,5, size=len(df31))
    df31["age"] = range(0,len(df31))
    ​
    df32["name"] = "input3"
    df32["unaregate"] = "in32"
    df32["value"] = np.random.randint(0,5, size=len(df32))
    df32["age"] = range(0,len(df32))
    ​
    df33["name"] = "input3"
    df33["unaregate"] = "in33"
    df33["value"] = np.random.randint(0,5, size=len(df33))
    df33["age"] = range(0,len(df33))
    ​
    df34["name"] = "input3"
    df34["unaregate"] = "in34"
    df34["value"] = np.random.randint(0,5, size=len(df34))
    df34["age"] = range(0,len(df34))
    frames = [df,df12,df13,df21,df22,df23,df31,df32,df33,df34]
    df = pd.concat(frames)
    df = df.drop([0],axis=1)
    

    这是我在绘图中采用的方法:

    fig = go.Figure()
    names = df.name.unique()
    for i in names:
        db = df[df["name"]==i]
        uni = db.unaregate.unique()
        for f in uni:
            fig.add_trace(go.Scatter(
                x=db[db.unaregate==f].age,
                y=db[db.unaregate==f].value,
            connectgaps=False ,visible=False,
            mode='lines', legendgroup=f,name=f))
    fig.update_layout(
        template="simple_white",
        xaxis=dict(title_text="age"),
        yaxis=dict(title_text="Value"),
        width=1000, height = 600
    )
    fig.update_layout(
        updatemenus=[
            dict(
    #             type="buttons",
    #             direction="down",
                active=0,
    #             x=0.7,
    #             y=1.2,
    #             showactive=True,
                buttons=list(
                    [ dict(
                            label="Select name",
                            method="update",
                            args=[
                                {"visible": [False,False,False,
                                             False,False,False,
                                             False,False,False,False
                                             ]},
                            ],
                        ),
                     dict(
                            label="input 1",
                            method="update",
                            args=[
                                {"visible": [True,True,True,
                                             False,False,False,
                                             False,False,False,False
                                             ]},
                            ],
                        ),
                     dict(
                            label="input 2",
                            method="update",
                            args=[
                                {"visible": [False,False,False,
                                             True,True,True,
                                             False,False,False,False
                                             ]},
                            ],
                        ),
                     dict(
                            label="input 3",
                            method="update",
                            args=[
                                {"visible": [False,False,False,
                                             False,False,False,
                                             True,True,True,True
                                             ]},
                            ],
                        ),
    ]
                ),
    #             showactive=True,
            )
        ]
    )
    fig
    

    0 回复  |  直到 5 年前
        1
  •  1
  •   Rob Raymond    5 年前
    • 可以简化数据帧的创建。使用 列表 理解
    • 绘声绘色地表达
      • 如果轨迹位于同一位置,则轨迹可见 名称 名称
    import pandas as pd
    import numpy as np
    import plotly.express as px
    
    df = (
        pd.DataFrame(
            [
                {
                    "name": f"input{a}",
                    "unaregate": f"in{a}{b}",
                    "value": np.random.randint(0, 5, 5),
                }
                for a in range(1, 4)
                for b in range(1, 4)
            ]
        )
        .explode("value")
        .pipe(lambda d: d.assign(age=np.random.randint(0, 5, len(d))))
    )
    
    # get valid combinations that will create traces
    combis = df.groupby(["name","unaregate"]).size().index
    
    # for this example - it's far simpler to use plotly express to create traces
    fig = px.line(df, x="age", y="value", color="unaregate").update_traces(visible=False)
    
    # use list comprehesions to populate visible lists
    fig.update_layout(
        updatemenus=[
            {
                "active": 0,
                "buttons": [
                    {
                        "label": "Select name",
                        "method": "update",
                        "args": [{"visible": [False for t in fig.data]}],
                    }
                ]
                + [
                    {
                        "label": n,
                        "method": "update",
                        "args": [{"visible": [n == t for t in combis.get_level_values(0)]}],
                    }
                    for n in combis.get_level_values(0).unique()
                ],
            }
        ],
        template="simple_white"
    )