#python #pandas #graph #plotly #plotly-dash
#python #панды #График #plotly #plotly-dash
Вопрос:
У меня есть графическая диаграмма, которая отслеживает текущие настроения для различных ключевых слов.
Я хочу, чтобы график отображался зеленым, когда настроение положительное, и красным, когда оно отрицательное.
Код:
app = dash.Dash(__name__)
app.layout = html.Div(
[ html.Div(className='container-fluid', children=[html.H2('Live Market Sentiment', style={'color':"#0C0F0A", 'text-align': 'center'}),
html.H5('Search Ticker/Stock:', style={'color':app_colors['text']}),
dcc.Dropdown(id='sentiment_term', options = [{'label':s,'value':s} for s in data_dict.keys()],value =['Google-GOOGL'], multi = False),
],
style={'width':'98%','margin-left':10,'margin-right':10,'max-width':50000})
@app.callback(Output('live-graph', 'figure'),
[Input(component_id='sentiment_term', component_property='value')],
events=[Event('graph-update', 'interval')])
def update_graph_scatter(sentiment_term):
var1 = str(data_dict[sentiment_term][0])
var2 = str(data_dict[sentiment_term][1])
try:
if sentiment_term:
df1 = pd.read_sql("SELECT sentiment.* FROM sentiment_fts fts LEFT JOIN sentiment ON fts.rowid = sentiment.id WHERE fts.sentiment_fts MATCH ? ORDER BY fts.rowid DESC LIMIT 1000", conn, params=(var1 '*',))
df2 = pd.read_sql("SELECT sentiment.* FROM sentiment_fts fts LEFT JOIN sentiment ON fts.rowid = sentiment.id WHERE fts.sentiment_fts MATCH ? ORDER BY fts.rowid DESC LIMIT 1000", conn, params=(var2 '*',))
df = df1.append(df2)
else:
df = pd.read_sql("SELECT * FROM sentiment ORDER BY id DESC, unix DESC LIMIT 1000", conn)
df.sort_values('unix', inplace=True)
df['date'] = pd.to_datetime(df['unix'], unit='ms')
df.set_index('date', inplace=True)
init_length = len(df)
df['sentiment_smoothed'] = df['sentiment'].rolling(int(len(df)/5)).mean()
df = df_resample_sizes(df)
X = df.index
Y = df.sentiment_smoothed.values
Y2 = df.volume.values
#df_count = pd.read_sql("SELECT * FROM sentiment ORDER BY id DESC LIMIT 1", conn)
#analyzer_count =df_count.id.max()
#print(analyzer_count)
data = plotly.graph_objs.Scatter(
x=X,
y=Y,
name='Sentiment',
mode= 'lines',
yaxis='y2',
fill="tozeroy",
fillcolor = "#8bcbfc"
)
return {'data': [data],'layout' : go.Layout(xaxis=dict(range=[min(X),max(X)]),
yaxis2=dict(range=[min(Y),max(Y)], side='left', overlaying='y',title='sentiment'),
title='Live sentiment for: "{}"'.format(sentiment_term),
font={'color':app_colors['text']},
plot_bgcolor = app_colors['background'],
paper_bgcolor = app_colors['background'],
showlegend=False)}
except Exception as e:
with open('errors.txt','a') as f:
f.write(str(e))
f.write('n')
Я попытался добавить условия if к диаграммам, но, похоже, это не помогло. пожалуйста, помогите!
Спасибо
Ответ №1:
Я знаю, что это не совсем точно отвечает на ваш вопрос, но вот некоторый начальный код, который я написал, чтобы предоставить вам связанный график. Я знаю, что это обычный графический код, но вы должны быть в состоянии довольно легко интегрировать это с вашим кодом Dash. Я много копался в Интернете, и оказалось, что Plotly не поддерживает несколько цветов для fill
опции как часть трассировки. Есть несколько решений, но они работают только в том случае, если значения y не сильно меняются между положительными и отрицательными значениями.
Вот некоторый начальный код, если значения не часто меняют знаки
# Import packages
import numpy as np
import pandas as pd
import plotly.graph_objects as go
# Generate some random data
numPts = 100
xData = pd.date_range(start='1/01/2020', end='12/31/2020', periods=numPts)
yDataPos = np.random.random(numPts//2)*4 # Random data [0, 4)
yDataNeg = (np.random.random(numPts//2) - 1)*2 # Random data [-2, 0)
# Create Plotly Plot
posData = go.Scatter(x=xData[0:numPts//2], y=yDataPos, fill='tonexty', line_color='green',
name='Trace 1', showlegend=True, legendgroup="mytrace")
negData = go.Scatter(x=xData[numPts//2:], y=yDataNeg, fill='tozeroy', line_color='red',
showlegend=False, legendgroup="mytrace")
fig = go.Figure(data=[posData,negData])
fig.update_layout(title='Live Sentiment')
fig.update_xaxes(title_text="Date")
fig.update_yaxes(title_text="Value")
Вам просто нужно добавить некоторую фильтрацию, чтобы определить, где ваши данные положительные, а где отрицательные, а затем вставить эти значения в соответствующие трассы.
Если значения часто меняют знак, я бы просто рекомендовал использовать гистограмму
allYData = yDataPos yDataNeg
colors = ['red' if val < 0 else 'green' for val in allYData]
dataTrace = go.Bar(x=xData, y=allYData, marker=dict(color=colors), name='Data')
fig = go.Figure(data=dataTrace)
fig.update_layout(title='Live Sentiment')
fig.update_xaxes(title_text="Date")
fig.update_yaxes(title_text="Value")