第二张图表未定义名称 Plotly Dash (Python)

Name is not defined for second chart Plotly Dash (Python)

1.我解析上传的数据和 return df_con: 结果:OK

def parse_data(contents, filename):
    content_type, content_string = contents.split(',')
    global df_con
    decoded = base64.b64decode(content_string)
    try:
        if 'csv' in filename:
            # Assume that the user uploaded a CSV or TXT file
            df_con = pd.read_csv(
                io.StringIO(decoded.decode('utf-8')))
        elif 'xls' in filename:
            # Assume that the user uploaded an excel file
            df_con = pd.read_excel(io.BytesIO(decoded))
        elif 'txt' or 'tsv' in filename:
            # Assume that the user upl, delimiter = r'\s+'oaded an excel file
            df_con = pd.read_csv(
                io.StringIO(decoded.decode('utf-8')), delimiter = r'\s+')
    except Exception as e:
        print(e)
        return html.Div([
            'There was an error processing this file.'
        ])

    return df_con

2。然后创建回调并进行分散。 结果:图表是正确的,但存在(小)错误“赋值前引用了局部变量‘df_con’”。

@app.callback(Output('graph3', 'figure'),
              [Input('upload-data', 'contents'),
                Input('upload-data', 'filename')])
def update_graph_upload(contents, filename):
    if contents:
        contents = contents[0]
        filename = filename[0]
        df_con = parse_data(contents, filename)
    fig2 = go.Figure(
        data=[
            go.Scatter(
                x=df_con['datetime'], 
                y=df_con['fact'], 
                mode='lines+markers')
            ],
        layout=go.Layout(
            plot_bgcolor=colors["graphBackground"],
            paper_bgcolor=colors["graphBackground"]
        ))
    return fig2

3。创建一个函数来分析上传的数据和 return dfcnb 结果:似乎没问题。 (正在处理其他脚本)

def bal_costs_df(df_con):

    con = pyodbc.connect(
        'Driver={SQL Server};'
        'Server=HTIC--DB1.RF.RES;'
        'Database=EKX;'
        'Trusted_Connection=yes;'
    )

    df_con['plan'] = df_con['fact'].shift(168)
    querystringnp = f"""
        SELECT [ELSPOTP_LT_DATE_ID],
                  [ELSPOTP_LT_TIME_ID],
                  [ELSPOTP_PRICE]
        FROM [ET_DWH].[dbo].[FactElspotPrices]
        WHERE ELSPOTP_PAREA_ID = 1
        ORDER BY ELSPOTP_LT_DATE_ID
    """
    cursor = con.cursor()
    df_np = pd.read_sql(querystringnp, con) 
    
    #Many other data manipulation and return....
            
    return dfcnb

4.尝试基于 df_con 和 bal_costs_df 函数创建另一个图表。 结果:得到错误名称‘df_con’未定义。

@app.callback(Output('graph4', 'figure'),
              [Input('upload-data', 'contents'),
                Input('upload-data', 'filename')])
def update_graph2(contents, filename):
    dfm = bal_costs_df(df_con)  <<<<<<<<<<<<ERROR: "name 'df_con' is not defined"
    fig3 = go.Figure(
        data=[
            go.Scatter(
                x=dfm['datetime'], 
                y=dfm['balcosts'], 
                mode='lines+markers')
            ],
        layout=go.Layout(
            plot_bgcolor=colors["graphBackground"],
            paper_bgcolor=colors["graphBackground"]
        ))
    return fig3

知道为什么 graph3 没问题,但 graph4 df_con 没有定义吗?也许输入错误? 我想要 dfcnb 数据框中的数据并从中创建图表。 谢谢

这是一个问题。任何时候此函数运行时内容具有假值,您永远不会定义 df_con。这至少会发生一次,在初始化期间,当回调以 None 输入值触发时。

def update_graph_upload(contents, filename):
    if contents:
        contents = contents[0]
        filename = filename[0]
        df_con = parse_data(contents, filename)

鉴于您需要 df_con,为此您需要 contents,我认为

可能会更好
if not contents:
    raise dash.exceptions.PreventUpdate
contents = contents[0]
filename = filename[0]
df_con = parse_data(contents, filename)

在最后一个示例中:

@app.callback(Output('graph4', 'figure'),
              [Input('upload-data', 'contents'),
                Input('upload-data', 'filename')])
def update_graph2(contents, filename):
    dfm = bal_costs_df(df_con)  <<<<<<<<<<<<ERROR: "name 'df_con' is not defined"

df_con 未在此函数内定义。我不建议尝试将其用作全局。如果你想在回调之间传递数据,那么我建议 dcc.Store component.