Dash 回调的输入中使用了不存在的对象

问题描述 投票:0回答:2

我是 Plotly/Dash 的新手。我正在尝试构建一个情绪分析仪表板。

我想用图表来表示“情绪”(实时数据:来自表格)到目前为止我已经达到了我的第一个目标:

我在 SQL 中选择:trump

@app.callback(
    Output("live-graph", "figure"),[Input('sentiment_term', 'value'), Input('graph-update', 'n_intervals')]
)
 #Output("wind-speed", "figure")
 #Input("wind-speed-update", "n_intervals")
 #Input("sentiment_term", "value")
 #Input("graph-update", "n_intervals")]

def gen_wind_speed(self, sentiment_term):



        conn = sqlite3.connect('twitter.db')
        c = conn.cursor()
        df = pd.read_sql("SELECT * FROM sentiment WHERE tweet LIKE '%trump%' ORDER BY unix DESC LIMIT 1000", conn)
        df.sort_values('unix', inplace=True)
        df['sentiment_smoothed'] = df['sentiment'].rolling(int(len(df)/5)).mean()
        df.dropna(inplace=True)

        X = df.unix.values[-100:]
        Y = df.sentiment_smoothed.values[-100:]

        data = plotly.graph_objs.Scatter(
                x=X,
                y=Y,
                name='Scatter',
                mode= 'lines+markers'
                )

        return {'data': [data],'layout' : go.Layout(xaxis=dict(range=[min(X),max(X)]),
                                                    yaxis=dict(range=[min(Y),max(Y)]),)}

现在作为第二个目标,我想生成(就在图表旁边)一个表格,其中包含图表中使用的数据(在本例中为twits)。 但是当我添加表格时,我得到:

Dash 回调的

Input
中使用了不存在的对象。该对象的 id 是
recent-table-update
,属性是
n_intervals
。当前布局中的字符串 ID 为:[live-graph、sentiment_term、graph-update、bin-slider、bin-auto、bin-size、wind-histogram、recent-tweets-table]

我不明白,因为我使用了之前相同的输入/输出“逻辑”

完整的代码,如果看起来组织不够,请道歉

import os
import pathlib
import numpy as np
import pandas as pd
import datetime as dt
import dash
import dash_core_components as dcc
import dash_html_components as html
import sqlite3
import plotly
import plotly.graph_objs as go
from dash.exceptions import PreventUpdate
from dash.dependencies import Input, Output, State
from scipy.stats import rayleigh



conn = sqlite3.connect('twitter.db', check_same_thread=False)


app_colors = {
    'pageBackground': '#272B30',
    'background': '#0C0F0A',
    'text': '#6699ff',
    'sentiment-plot':'#41EAD4',
    'volume-bar':'#6699ff',
    'someothercolor':'#80aaff',
    'papercolor':'#1E2022',
    'plotcolor':'#262626',
    'fillcolor':'#ff6666',
    'gridcolor': '#737373',
    'backgroundTableHeaders': '#001133',
    'backgroundTableRows': '#002266'
}

POS_NEG_NEUT = 0.1

MAX_DF_LENGTH = 100


GRAPH_INTERVAL = os.environ.get("GRAPH_INTERVAL", 5000)

app = dash.Dash(
    __name__,
    meta_tags=[{"name": "viewport", "content": "width=device-width, initial-scale=1"}],
)

server = app.server

app_colorsor = {"graph_bg": "#082255", "graph_line": "#007ACE"}

app.layout = html.Div(
    [
        # header
        html.Div(
            [
                html.Div(
                    [
                        html.H4("Twitter STREAMING", className="app__header__title"),
                        html.P(
                            "This app continually queries a SQL database and displays live charts of twitter sentiment analysis.",
                            className="app__header__title--grey",
                        ),
                    ],
                    className="app__header__desc",
                ),
                html.Div(
                    [
                        html.Img(
                            src=app.get_asset_url("twitter_logo.png"),
                            className="app__menu__img",
                        )
                    ],
                    className="app__header__logo",
                ),
            ],
            className="app__header",
        ),
        html.Div(
            [
                #Plot sentiment
                html.Div(
                    [
                        html.Div(
                            [html.H6("Plot sentiment", className="graph__title")]
                        ),

                        dcc.Graph(
                            id="live-graph",
                            animate=False


                         ),


                         dcc.Input(
                            id="sentiment_term",
                            value="twitter",
                            type="text"
                        ),

                        dcc.Interval(
                        id="graph-update",
                        interval=1*1000,
                        n_intervals=0


                        ),
                    ],
                    className="two-thirds column container",
                ),
                html.Div(
                    [
                        # Recent tweets table
                        html.Div(
                            [
                                html.Div(
                                    [
                                        html.H6(
                                            "Recent tweets table",
                                            className="graph__title",
                                        )
                                    ]
                                ),
                                html.Div(
                                    [
                                        dcc.Slider(
                                            id="bin-slider",
                                            min=1,
                                            max=60,
                                            step=1,
                                            value=20,
                                            updatemode="drag",
                                            marks={
                                                20: {"label": "20"},
                                                40: {"label": "40"},
                                                60: {"label": "60"},
                                            },
                                        )
                                    ],
                                    className="slider",
                                ),
                                html.Div(
                                    [
                                        dcc.Checklist(
                                            id="bin-auto",
                                            options=[
                                                {"label": "Auto", "value": "Auto"}
                                            ],
                                            value=["Auto"],
                                            inputClassName="auto__checkbox",
                                            labelClassName="auto__label",
                                        ),
                                        html.P(
                                            "# of Bins: Auto",
                                            id="bin-size",
                                            className="auto__p",
                                        ),
                                    ],
                                    className="auto__container",
                                ),
                              #it says wind because I got it from a wind direction Dash template
                                dcc.Graph(
                                    id="wind-histogram",
                                    figure=dict(
                                        layout=dict(
                                            plot_bgcolor=app_colorsor["graph_bg"],
                                            paper_bgcolor=app_colorsor["graph_bg"],
                                        )
                                    ),
                                ),
                            ],
                            className="graph__container first",
                        ),
                        # Table that I would like to add
                         html.Div(
                                    [
                                        html.H6(
                                            "Recent tweets table",
                                            className="graph__title",
                                        )
                                    ]
                                ),


                         html.Div(id="recent-tweets-table", children=[
                                      html.Thead(html.Tr( children=[], style={'color': app_colorsors['text']})),
                                      html.Tbody([html.Tr(children=[], style={'color': app_colorsors['text'],
                                                            'background-color': app_colors['backgroundTableRows'],
                                                            'border':'0.2px', 'font - size':'0.7rem'}
                                      ],

                               className='col s12 m6 l6', style={'width':'98%', 'margin-top':30, 'margin-left':15,
                                                       'margin-right':15,'max-width':500000}

                        ),
                    ],
                    className="one-third column histogram__direction",
                ),
            ],
            className="app__content",
        ),
    ],
    className="app__container",
)





dcc.Interval(
id='recent-table-update',
interval=2*1000,
n_intervals=0),




#def get_current_time():


    #now = dt.datetime.now()
    #total_time = (now.hour * 3600) + (now.minute * 60) + (now.second)
    #return total_time

def df_resample_sizes(df, maxlen=MAX_DF_LENGTH):
    df_len = len(df)
    resample_amt = 100
    vol_df = df.copy()
    vol_df['volume'] = 1

    ms_span = (df.index[-1] - df.index[0]).seconds * 1000
    rs = int(ms_span / maxlen)

    df = df.resample('{}ms'.format(int(rs))).mean()
    df.dropna(inplace=True)

    vol_df = vol_df.resample('{}ms'.format(int(rs))).sum()
    vol_df.dropna(inplace=True)

    df = df.join(vol_df['volume'])

    return df

@app.callback(
    Output("live-graph", "figure"),[Input('sentiment_term', 'value'), Input('graph-update', 'n_intervals')]
)
 #Output("wind-speed", "figure")
 #Input("wind-speed-update", "n_intervals")
 #Input("sentiment_term", "value")
 #Input("graph-update", "n_intervals")]

def gen_wind_speed(self, sentiment_term):



        conn = sqlite3.connect('twitter.db')
        c = conn.cursor()
        df = pd.read_sql("SELECT * FROM sentiment WHERE tweet LIKE '%trump%' ORDER BY unix DESC LIMIT 1000", conn)
        df.sort_values('unix', inplace=True)
        df['sentiment_smoothed'] = df['sentiment'].rolling(int(len(df)/5)).mean()
        df.dropna(inplace=True)

        X = df.unix.values[-100:]
        Y = df.sentiment_smoothed.values[-100:]

        data = plotly.graph_objs.Scatter(
                x=X,
                y=Y,
                name='Scatter',
                mode= 'lines+markers'
                )

        return {'data': [data],'layout' : go.Layout(xaxis=dict(range=[min(X),max(X)]),
                                                    yaxis=dict(range=[min(Y),max(Y)]),)}


def generate_table(df, max_rows=20):
    return html.Table(className="responsive-table",
                      children=[
                          html.Thead(
                              html.Tr(
                                  children=[
                                      html.Th(col.title()) for col in df.columns.values],
                                  style={'color': app_colorsors['text'],
                                         'background-color': app_colorsors['backgroundTableHeaders']}
                              )
                          ),
                          html.Tbody(
                              [
                                  html.Tr(
                                      children=[
                                          html.Td(data) for data in d
                                      ], style={'color': app_colorsors['text'],
                                                'background-color': quick_color(d[2]),
                                                'border':'0.2px', 'font - size':'0.7rem'}
                                  )
                                  for d in df.values.tolist()])
                      ]
                      )



@app.callback(Output("recent-tweets-table", "children"),[Input('sentiment_term','value'), Input('recent-table-update', 'n_intervals')]
 )

def update_recent_tweets(self, sentiment_term):
    genTable = html.Table()
    try:
        conn = sqlite3.connect('twitter.db')
        df = pd.read_sql("SELECT UnixTime, Tweet, Polarity FROM %s ORDER BY UnixTime DESC LIMIT 20" % (RunConfig.tableName), conn)
        if len(df)>0:
            df['Date'] = pd.to_datetime(df['UnixTime'], unit='ms')

            df = df.drop(['UnixTime'], axis=1)
            df = df[['Date', 'Tweet', 'Polarity']]
            df.Polarity = df.Polarity.round(3)

            genTable = generate_table(df, max_rows=10)

    except Exception as e:
        with open('errors.txt','a') as f:
            f.write("update_recent_tweets: " + str(e))
            f.write('\n')

    return genTable






if __name__ == "__main__":
    app.run_server(debug=True)
python-3.x user-interface flask plotly plotly-dash
2个回答
3
投票

我认为问题在于您在回调中引入了一个不存在(尚未)的元素作为输入。该元素是“recent-table-update”,在更新表之前它不存在。为了避免这种情况,您应该将其作为状态引入回调中(它不会触发回调,代码也不会中断)。更多信息:链接

这是您的代码:

@app.callback(
Output("recent-tweets-table", "children"),
[Input('sentiment_term','value'), 
Input('recent-table-update', 'n_intervals')]
 )

这是我建议的代码:

@app.callback(
Output("recent-tweets-table", "children"),
Input('sentiment_term','value'), 
State('recent-table-update', 'n_intervals')
 )

0
投票

如果它比上面的解决方案更能帮助其他人,请检查您是否在布局内调用有问题的 id。在某些情况下,例如当连接应用程序调用时(例如,当使用下拉列表的输出作为输入的输入时),您可能需要在布局中隐藏的某个位置进行显式调用。

要解决此问题,您可以在布局内的某个位置指定

html.Div(id='recent-table-update')
,这将不会输出任何内容,但会激活应用程序调用。在这里,
id
与您有问题的
id
相同。

© www.soinside.com 2019 - 2024. All rights reserved.