Я новичок в Plotly / Da sh. Я пытаюсь создать панель анализа настроений.
Я хотел бы представить «настроения» на графике ( данные в реальном времени данные: из таблицы). Я достиг своей первой цели :
Я выбираю: козырь в моем SQL.
@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 ), используемыми на графике. Но когда я добавляю таблицу, я получил:
Несуществующий объект использовался в Input
обратного вызова Da sh. Идентификатор этого объекта - recent-table-update
, а свойство - n_intervals
. Идентификаторы строк в текущем макете: [live-graph, sentiment_term, graph-update, bin-slider, bin-auto, bin-size, wind-histogram, latest-tweets-table]
Этого я не понимаю, так как я использовал тот же «logi c» ввода / вывода, что и до
Полный код, приносит свои извинения, если он не выглядит организованным достаточно
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)