gpt4 book ai didi

Python Dash 刷新页面不更新源数据

转载 作者:行者123 更新时间:2023-12-04 01:15:30 26 4
gpt4 key购买 nike

我编写了一个基本的 plotly dash 应用程序,它从 csv 中提取数据并将其显示在图表上。
然后,您可以在应用程序上切换值并更新图表。
但是,当我将新数据添加到 csv(每天执行一次)时,应用程序不会在刷新页面时更新数据。
解决方法通常是将 app.layout 定义为函数,如 here 所述(向下滚动到页面加载更新)。你会在我下面的代码中看到我已经做到了。
这是我的代码:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import numpy as np

import pandas as pd

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

path = 'https://raw.githubusercontent.com/tbuckworth/Public/master/CSVTest.csv'

df = pd.read_csv(path)
df2 = df[(df.Map==df.Map)]


def layout_function():

df = pd.read_csv(path)
df2 = df[(df.Map==df.Map)]

available_strats = np.append('ALL',pd.unique(df2.Map.sort_values()))
classes1 = pd.unique(df2["class"].sort_values())
metrics1 = pd.unique(df2.metric.sort_values())

return html.Div([
html.Div([
dcc.Dropdown(
id="Strategy",
options=[{"label":i,"value":i} for i in available_strats],
value=list(available_strats[0:1]),
multi=True
),
dcc.Dropdown(
id="Class1",
options=[{"label":i,"value":i} for i in classes1],
value=classes1[0]
),
dcc.Dropdown(
id="Metric",
options=[{"label":i,"value":i} for i in metrics1],
value=metrics1[0]
)],
style={"width":"20%","display":"block"}),

html.Hr(),

dcc.Graph(id='Risk-Report')
])

app.layout = layout_function


@app.callback(
Output("Risk-Report","figure"),
[Input("Strategy","value"),
Input("Class1","value"),
Input("Metric","value"),
])

def update_graph(selected_strat,selected_class,selected_metric):
if 'ALL' in selected_strat:
df3 = df2[(df2["class"]==selected_class)&(df2.metric==selected_metric)]
else:
df3 = df2[(df2.Map.isin(selected_strat))&(df2["class"]==selected_class)&(df2.metric==selected_metric)]
df4 = df3.pivot_table(index=["Fund","Date","metric","class"],values="value",aggfunc="sum").reset_index()
traces = []
for i in df4.Fund.unique():
df_by_fund = df4[df4["Fund"] == i]
traces.append(dict(
x=df_by_fund["Date"],
y=df_by_fund["value"],
mode="lines",
name=i
))

if selected_class=='USD':
tick_format=None
else:
tick_format='.2%'

return {
'data': traces,
'layout': dict(
xaxis={'type': 'date', 'title': 'Date'},
yaxis={'title': 'Values','tickformat':tick_format},
margin={'l': 40, 'b': 40, 't': 10, 'r': 10},
legend={'x': 0, 'y': 1},
hovermode='closest'
)
}


if __name__ == '__main__':
app.run_server(debug=True)
我尝试过的事情
  • 删除 df = pd.read_csv(path) 之前的初始 def layout_function(): 。这会导致错误。
  • 使用以下代码创建回调按钮以刷新数据:
  • @app.callback(
    Output('Output-1','children'),
    [Input('reload_button','n_clicks')]
    )

    def update_data(nclicks):
    if nclicks == 0:
    raise PreventUpdate
    else:
    df = pd.read_csv(path)
    df2 = df[(df.Map==df.Map)]
    return('Data refreshed. Click to refresh again')
    这不会产生错误,但按钮也不会刷新数据。
  • df 回调中定义 update_graph。每次切换时都会更新数据,这是不切实际的(我的真实数据 > 10^6 行,所以我不想每次用户更改切换值时都读取它)

  • 简而言之,我认为定义 app.layout = layout_function 应该可以完成这项工作,但事实并非如此。我错过了什么/没有看到什么?
    感谢任何帮助。

    最佳答案

    TLDR;我建议您只需从回调中加载数据。如果加载时间太长,您可以更改格式(例如更改为 feather )和/或通过预处理减少数据大小。如果这仍然不够快,下一步是将数据存储在服务器端内存缓存中,例如 Redis

    由于您在 df 中重新分配 df2layout_function ,这些变量被视为 local in Python ,因此您不会从全局范围修改 dfdf2 变量。虽然您可以使用 global keywordthe use of global variables is discouraged in Dash 实现此行为。
    Dash 中的标准方法是在回调中(或在 layout_function 中)加载数据并将其存储在 Store 对象(或等效的隐藏 Div )中。结构将类似于

    import pandas as pd
    import dash_core_components as dcc
    from dash.dependencies import Output, Input

    app.layout = html.Div([
    ...
    dcc.Store(id="store"), html.Div(id="trigger")
    ])

    @app.callback(Output('store','data'), [Input('trigger','children')], prevent_initial_call=False)
    def update_data(children):
    df = pd.read_csv(path)
    return df.to_json()

    @app.callback(Output("Risk-Report","figure"), [Input(...)], [State('store', 'data')])
    def update_graph(..., data):
    if data is None:
    raise PreventUpdate
    df = pd.read_json(data)
    ...
    但是,这种方法通常比仅从回调内部的磁盘读取数据慢得多(这似乎是您试图避免的),因为它会导致数据在服务器和客户端之间传输。

    关于Python Dash 刷新页面不更新源数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63502062/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com