如何使用下拉菜单更新第三个情节?

Posted

技术标签:

【中文标题】如何使用下拉菜单更新第三个情节?【英文标题】:How can I update the third plot in plotly with dropdown menu? 【发布时间】:2022-01-06 07:10:36 【问题描述】:

我有类似here 的问题。我也试过你的解决方案。但这一次,我有三个痕迹。两张图在同一个图中。第三个是桌子。这是我的代码:


import pandas as pd
import plotly.tools as plotly_tools
import plotly.graph_objs as go
from plotly.subplots import make_subplots

df1 = pd.DataFrame("SALES_DATE" : ["2020-01-01", "2020-02-01", "2020-03-01", "2020-04-01", "2020-05-01", 
                                    "2020-01-01", "2020-02-01", "2020-03-01", "2020-04-01", "2020-05-01", 
                                    "2020-01-01", "2020-02-01", "2020-03-01", "2020-04-01", "2020-05-01"],
                    "y" : [12, 10, 11, np.nan, np.nan, 12, 10, 11, np.nan, np.nan, 12, 10, 11, np.nan, np.nan],
                    "y_hat" : [np.nan, np.nan, np.nan, 10, 12, np.nan, np.nan, np.nan, 10, 12, np.nan, np.nan, np.nan, 10, 12],
                    "ITEM_ID" : ["32_2_1004", "32_2_1004", "32_2_1004", "32_2_1004", "32_2_1004", 
                                 "32_2_1005", "32_2_1005", "32_2_1005", "32_2_1005", "32_2_1005", 
                                 "32_2_1006", "32_2_1006", "32_2_1006", "32_2_1006", "32_2_1006"]
                   )

df2 = pd.DataFrame("ITEM_ID": ["32_2_1004", "32_2_1005", "32_2_1006"],
                   "PREDICTION_ERROR": [2, 1, 0],
                   "PREDICTION": [22, 23, 24])

item_list = ["32_2_1004", "32_2_1005", "32_2_1006"]

def make_multi_plot(df1, df2, item_list):
    
    date_time = str(datetime.datetime.now())[0:16].replace(':','-').replace(' ','_')
    
    with open('Model_Raporu_'+date_time+'.html', 'a') as f:
        
        fig = make_subplots(rows=2, 
                        cols=1,
                        shared_xaxes=True,
                        vertical_spacing=0.05,
                        specs = [[], ["type": "table"]]
                       )

        for item_id in item_list:
            
            trace1 = go.Scatter(
                x=df1.loc[df1.ITEM_ID.isin([item_id])].SALES_DATE, 
                y=df1.loc[df1.ITEM_ID.isin([item_id])].y,
                mode='lines+markers',
                name = "orjinal - " + str(item_id))
            fig.append_trace(trace1,1,1)
            
            trace1x = go.Scatter(
                x=df1.loc[df1.ITEM_ID.isin([item_id])].SALES_DATE, 
                y=df1.loc[df1.ITEM_ID.isin([item_id])].y_hat,
                mode='lines+markers',
                name = "tahmin - " + str(item_id))
            fig.append_trace(trace1x,1,1)
        
            trace2 = go.Table(    
                header = dict(
                values = df2[df2.ITEM_ID.isin([item_id])].columns.tolist(),
                font = dict(size=10),
                align = "left"),
                cells = dict(
                values = [df2[df2.ITEM_ID.isin([item_id])][k].tolist() for k in df2[df2.ITEM_ID.isin([item_id])].columns[:]],
                align = "left"
                )
            )
            fig.append_trace(trace2,2,1)
        
        Ld = len(fig.data)
        Lc = len(item_list)
        for k in range(3, Ld):
            fig.update_traces(visible=False, selector = k)
    
        def create_layout_button(k, item_id):
            
            visibility= [False]*3*Lc
            for tr in [3*k, 3*k+1]:
                visibility[tr] =True
            return dict(label = item_id,
                        method = 'restyle',
                        args = ['visible': visibility,
                                 'title': item_id,
                                 'showlegend': True])    
    

        fig.update_layout(
           updatemenus=[go.layout.Updatemenu(
           active = 0,
           buttons = [create_layout_button(k, item_id) for k, item_id in enumerate(item_list)],
           x = 0.5,
           y = 1.15
           )
        ],
           title = 'Model Raporu',
           template = 'plotly_dark',
           height=800
       )
    
        fig.show()
        f.write(fig.to_html(full_html=False, include_plotlyjs='cdn'))

make_subplots(df1=df1, df2=df2, item_list=item_list)

更改下拉按钮时,只有上图会发生变化。但表保持不变。我无法通过下拉菜单更改它。这是图片:

report

如何使用下拉菜单更改表格?

【问题讨论】:

创建最小的工作代码,我们可以简单地复制和运行。 我刚刚添加了一个工作代码。一个示例数据集。 最后一行应该是make_multi_plot而不是make_subplots。你忘了import numpy as np, import datetime 更简单的date_time = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M') 当我运行此代码并在下拉列表中选择时,它不会更改绘图或表格。 【参考方案1】:

如果您使用print() 查看变量中的值,那么对于visibility,您应该会看到

[True, True, False, False, False, False, False, False, False]
[False, False, False, True, True, False, False, False, False]
[False, False, False, False, False, False, True, True, False]

所以每个列表只有 2 个 True 但他们应该有 3 个 True

你创建了错误的列表visibility - 你必须添加3*k+2

for tr in [3*k, 3*k+1, 3*k+2]:
    visibility[tr] = True

完整的工作代码。

当我使用dropdown 时,我更改了df 中的一些值以查看不同的情节。

import pandas as pd
import plotly.tools as plotly_tools
import plotly.graph_objs as go
from plotly.subplots import make_subplots
import numpy as np
import datetime

# --- functions ---

def make_multi_plot(df1, df2, item_list):
    
    #date_time = str(datetime.datetime.now())[0:16].replace(':','-').replace(' ','_')
    #print(date_time)
    
    date_time = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M')
    #print(date_time)

    with open('Model_Raporu_'+date_time+'.html', 'a') as f:
        
        fig = make_subplots(rows=2, 
                        cols=1,
                        shared_xaxes=True,
                        vertical_spacing=0.05,
                        specs = [[], ["type": "table"]]
                       )

        for item_id in item_list:
            #print('item_id:', item_id)
            
            trace1 = go.Scatter(
                x=df1.loc[df1.ITEM_ID.isin([item_id])].SALES_DATE, 
                y=df1.loc[df1.ITEM_ID.isin([item_id])].y,
                mode='lines+markers',
                name = "orjinal - " + str(item_id))
            fig.append_trace(trace1, 1, 1)
            
            trace1x = go.Scatter(
                x=df1.loc[df1.ITEM_ID.isin([item_id])].SALES_DATE, 
                y=df1.loc[df1.ITEM_ID.isin([item_id])].y_hat,
                mode='lines+markers',
                name = "tahmin - " + str(item_id))
            fig.append_trace(trace1x,1,1)
            
            trace2 = go.Table(    
                header=dict(
                    values = df2[df2.ITEM_ID.isin([item_id])].columns.tolist(),
                    font = dict(size=10),
                    align = "left"
                ),
                cells = dict(
                    values = [df2[df2.ITEM_ID.isin([item_id])][k].tolist() for k in df2[df2.ITEM_ID.isin([item_id])].columns[:]],
                    align = "left"
                )
            )
            fig.append_trace(trace2,2,1)
        
        Ld = len(fig.data)
        Lc = len(item_list)
        
        for k in range(3, Ld):
            fig.update_traces(visible=False, selector=k)
    
        def create_layout_button(k, item_id):
            #print(k, item_id)
            
            visibility = [False]*3*Lc
            for tr in [3*k, 3*k+1, 3*k+2]:
                visibility[tr] = True
                
            #print(visibility)
                
            return dict(label = item_id,
                        method = 'restyle',
                        args = ['visible': visibility,
                                 'title': item_id,
                                 'showlegend': True])    
    

        fig.update_layout(
           updatemenus=[go.layout.Updatemenu(
               active=0,
               buttons=[create_layout_button(k, item_id) for k, item_id in enumerate(item_list)],
               x=0.5,
               y=1.15
           )],
           title='Model Raporu',
           template='plotly_dark',
           height=800
        )
    
        fig.show()
        f.write(fig.to_html(full_html=False, include_plotlyjs='cdn'))

# --- main ---

df1 = pd.DataFrame(
    "SALES_DATE": [
        "2020-01-01", "2020-02-01", "2020-03-01", "2020-04-01", "2020-05-01", 
        "2020-01-01", "2020-02-01", "2020-03-01", "2020-04-01", "2020-05-01", 
        "2020-01-01", "2020-02-01", "2020-03-01", "2020-04-01", "2020-05-01",
    ],
    "y": [
        12, 10, 11, np.nan, np.nan,
        12, 15, 11, np.nan, np.nan,
        12, 10, 21, np.nan, np.nan,
    ],
    "y_hat": [
        np.nan, np.nan, np.nan, 10, 12,
        np.nan, np.nan, np.nan, 15, 12,
        np.nan, np.nan, np.nan, 12, 12,
    ],
    "ITEM_ID": [
        "32_2_1004", "32_2_1004", "32_2_1004", "32_2_1004", "32_2_1004", 
        "32_2_1005", "32_2_1005", "32_2_1005", "32_2_1005", "32_2_1005", 
        "32_2_1006", "32_2_1006", "32_2_1006", "32_2_1006", "32_2_1006",
    ]
)

df2 = pd.DataFrame(
    "ITEM_ID": ["32_2_1004", "32_2_1005", "32_2_1006"],
    "PREDICTION_ERROR": [2, 1, 0],
    "PREDICTION": [22, 23, 24]
)

item_list = ["32_2_1004", "32_2_1005", "32_2_1006"]


make_multi_plot(df1=df1, df2=df2, item_list=item_list)

【讨论】:

非常感谢您的解决方案。它对我有用,我现在理解逻辑。如果你来土耳其,我会给你买咖啡。 :)

以上是关于如何使用下拉菜单更新第三个情节?的主要内容,如果未能解决你的问题,请参考以下文章

使用 thymeleaf、spring boot 的动态下拉菜单

如何使用 Capybara 在下拉菜单中选择选项

未使用下拉菜单选择更新散景图

如何使用不同的下拉菜单更新绘图破折号

根据第一个和第二个菜单选择填充第三个下拉菜单

如何使用单元格旁边的下拉菜单对当前日期进行单元格更新?