【问题标题】:how to fill colors on a plotly chart based on Y axis values?如何根据 Y 轴值在绘图图表上填充颜色?
【发布时间】:2021-01-28 06:12:14
【问题描述】:

我有一个图表,可以跟踪各种关键字的实时情绪。

我希望图表在情绪为正面时显示为绿色,在情绪为负面时显示为红色。

代码:

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 条件,但似乎没有帮助。请帮忙!

谢谢

【问题讨论】:

    标签: python pandas graph plotly plotly-dash


    【解决方案1】:

    我知道这并不能完全回答您的问题,但这是我编写的一些入门代码,旨在为您提供相关的情节。我知道这是常规的 Plotly 代码,但您应该能够相当轻松地将其与您的 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")
    

    【讨论】:

      猜你喜欢
      • 2020-05-22
      • 1970-01-01
      • 2022-09-27
      • 1970-01-01
      • 2021-01-13
      • 1970-01-01
      • 2018-09-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多