1
votes

I have been researching the Plotly-Dash library not too long ago. There was a callback problem on the second graph .. I can't figure out what is the reason. I have been understanding the components for a long time but have not found the reason. However, in the first graph, the callbacks do work.

enter image description here

here is my code:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objs as go
import sqlite3
import pytz

import pandas as pd
import numpy as np
from datetime import datetime

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = dash.Dash(__name__)


def get_value(n_intervals):
    timezone = pytz.timezone("Etc/UTC")
    utc_from = datetime(2021, 3, 23, tzinfo=timezone)
    
    base = sqlite3.connect('base_eurousd.db')
   
    cur = base.cursor()
    
    read_db = cur.execute('SELECT * FROM data_eurusd').fetchall()
    df = pd.DataFrame(read_db)
    df[0] = pd.to_datetime(df[0], unit='ms')
    df[3] = np.where(df[1].diff().lt(0) | df[2].diff().lt(0), df[3] * -1, df[3])

    return df


def get_value_analyze(n_intervals):
    timezone = pytz.timezone("Etc/UTC")
    utc_from = datetime(2021, 3, 23, tzinfo=timezone)
   
    base = sqlite3.connect('base_eurousd.db')
   
    cur = base.cursor()
 
    read_db = cur.execute('SELECT * FROM data_eurusd').fetchall()
    res = pd.DataFrame(read_db)

    res[0] = pd.to_datetime(res[0], unit='ms')
    res[3] = np.where(res[1].diff().lt(0) | res[2].diff().lt(0), res[3] * -1, res[3])

    funcs = {
        "bid_open": (1, 'first'),
        "bid_close": (1, 'last'),
        "tiks": (0, 'size'),
        "ask_open": (2, 'first'),
        "ask_close": (2, 'last'),
        "bid_min": (1, 'min'),
        "bid_max": (1, 'max'),
        "ask_min": (2, 'min'),
        "ask_max": (2, 'max'),
        "qvant": (3, 'quantile'),
        "sred": (3, 'mean'),
        "skew": (3, 'skew'),
        ">0": (3, lambda x: x.lt(0).sum()),
        "=0": (3, lambda x: x.eq(0).sum()),
        "<0": (3, lambda x: x.gt(0).sum())
    }
    res1 = res.groupby(pd.Grouper(key=0, freq="1T")).agg(**funcs)
    return res1



def serve_layout():
    return html.Div(
        children=[
            html.H4(children='111'),
            html.Div(id='my-id', children='''EURUSD'''),
            dcc.Graph(id='example-graph', animate=True, responsive=True),
            dcc.Interval(
                id='interval-component',
                interval=3 * 1000,
                n_intervals=0,
            ),
            html.Div(id='my-id2', children='''NO UPDATE'''),
            dcc.Graph(id='example-graph-2', animate=True, responsive=True),
            dcc.Interval(
                id='interval-component2',
                interval=3 * 1000,
                n_intervals=0,
            ),
        ],
    )


app.layout = serve_layout


@app.callback(
    Output('example-graph', 'figure'),
    [Input('interval-component', 'n_intervals')])
def update_graph(n_intervals):
    df = get_value(n_intervals)

    return \
        {
            'data': [
                {'x': df[0], 'y': df[1], 'type': 'line', 'name': 'BID'},
            ],
            'layout': go.Layout(xaxis=dict(range=[min(df[0]), max(df[0])]),
                                yaxis=dict(range=[min(df[1]), max(df[1])]), )
        }



@app.callback(
    Output('example-graph-2', 'figure'),
    [Input('interval-component2', 'n_intervals')])
def update_graph_2(n_intervals):
    res1 = get_value_analyze(n_intervals)
    return \
        {
            'data': [
                {'x': res1[0], 'y': res1[3], 'type': 'line', 'name': 'ТИК'},
                {'x': res1[0], 'y': res1[10], 'type': 'line', 'name': 'КВАНТИЛЬ'},
                {'x': res1[0], 'y': res1[11], 'type': 'line', 'name': 'СПРЕД'},
                {'x': res1[0], 'y': res1[12], 'type': 'line', 'name': 'SKEW'},
                {'x': res1[0], 'y': res1[13], 'type': 'line', 'name': 'МЕНЬШЕ НУЛЯ'},
                {'x': res1[0], 'y': res1[13], 'type': 'line', 'name': 'МЕНЬШЕ НУЛЯ'},
                {'x': res1[0], 'y': res1[14], 'type': 'line', 'name': 'РАВНО НУЛЮ'},
                {'x': res1[0], 'y': res1[15], 'type': 'line', 'name': 'БОЛЬШЕ НУЛЯ'},
            ],
        }


if __name__ == '__main__':
    app.run_server(debug=True)

Please tell me the solution to this problem?

This Error:

[2021-06-28 23:16:10,613] ERROR in app: Exception on /_dash-update-component [POST]
Traceback (most recent call last):
  File "C:\Users\neket\AppData\Roaming\Python\Python39\site-packages\pandas\core\indexes\base.py", line 3080, in get_loc
    return self._engine.get_loc(casted_key)
  File "pandas\_libs\index.pyx", line 70, in pandas._libs.index.IndexEngine.get_loc
  File "pandas\_libs\index.pyx", line 101, in pandas._libs.index.IndexEngine.get_loc
  File "pandas\_libs\hashtable_class_helper.pxi", line 4554, in pandas._libs.hashtable.PyObjectHashTable.get_item
  File "pandas\_libs\hashtable_class_helper.pxi", line 4562, in pandas._libs.hashtable.PyObjectHashTable.get_item
KeyError: 0

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\neket\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\neket\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\neket\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\neket\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "C:\Users\neket\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\neket\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\neket\AppData\Local\Programs\Python\Python39\lib\site-packages\dash\dash.py", line 1079, in dispatch
    response.set_data(func(*args, outputs_list=outputs_list))
  File "C:\Users\neket\AppData\Local\Programs\Python\Python39\lib\site-packages\dash\dash.py", line 1010, in add_context
    output_value = func(*args, **kwargs)  # %% callback invoked %%
  File "C:\Users\neket\OneDrive\Рабочий стол\MT5 CODE\TEST_PANDAS_DASH.py", line 120, in update_graph_2
    {'x': res1[0], 'y': res1[3], 'type': 'line', 'name': 'ТИК'},
  File "C:\Users\neket\AppData\Roaming\Python\Python39\site-packages\pandas\core\frame.py", line 3024, in __getitem__
    indexer = self.columns.get_loc(key)
  File "C:\Users\neket\AppData\Roaming\Python\Python39\site-packages\pandas\core\indexes\base.py", line 3082, in get_loc
    raise KeyError(key) from err
KeyError: 0

Output from df:

                            0        1        2  3
0     2021-06-30 18:33:24.471  1.18550  1.18552  2
1     2021-06-30 18:33:26.073  1.18552  1.18555  6
2     2021-06-30 18:33:26.173  1.18553  1.18555  2
3     2021-06-30 18:33:26.273  1.18553  1.18554 -4
4     2021-06-30 18:33:26.381  1.18552  1.18554 -2
...                       ...      ...      ... ..
36331 2021-07-01 07:50:54.126  1.18489  1.18491  2
36332 2021-07-01 07:51:01.297  1.18489  1.18491  2
36333 2021-07-01 07:51:13.108  1.18489  1.18493  4
36334 2021-07-01 07:51:16.078  1.18490  1.18493  2
36335 2021-07-01 07:51:31.511  1.18489  1.18493 -2

Output from res1:

                    bid_open  bid_close  tiks  ask_open  ...      skew  >0  =0  <0
0                                                         ...                      
2021-06-28 08:30:00   1.19259    1.19259     5   1.19263  ... -0.567163   2   0   3
2021-06-28 08:31:00   1.19259    1.19269    57   1.19261  ... -0.182745  25   0  32
2021-06-28 08:32:00   1.19269    1.19278    90   1.19272  ... -0.008905  44   0  46
2021-06-28 08:33:00   1.19278    1.19277    62   1.19281  ...  0.010950  31   0  31
2021-06-28 08:34:00   1.19277    1.19282    61   1.19281  ...  0.033526  31   0  30
...                       ...        ...   ...       ...  ...       ...  ..  ..  ..
2021-06-28 17:14:00   1.19254    1.19248   157   1.19255  ... -0.050396  76   0  81
2021-06-28 17:15:00   1.19248    1.19257    81   1.19252  ... -0.161537  36   0  45
2021-06-28 17:16:00   1.19258    1.19247   107   1.19260  ...  0.046116  54   0  53
2021-06-28 17:17:00   1.19247    1.19275    77   1.19250  ... -0.415599  29   0  48
2021-06-28 17:18:00   1.19275    1.19304    68   1.19278  ... -0.398739  26   0  42

[529 rows x 15 columns]

Link to base : https://cloud.mail.ru/public/gtDi/BCgw1Jk8r

1
What is the exact error message you receive?bk_
updated the questionxxxHEKETOSxxx
Look at the value of res1 and the function where you get its value get_value_analyze. It would help if you also include part of the data, some insert statements, so we can easily reproduce the problem.Bas van der Linden
My memory may not be accurate, but isn't a list unnecessary in a callback function?r-beginners
updated the query, added a link to the database. However, it seems to me that the problem is not with the data, but with the callbackxxxHEKETOSxxx

1 Answers

1
votes

Let's compare the dataframe used in the update_graph callback (df) to the dataframe used in the update_graph_2 callback (res1):

# inside update_graph callback 
df = get_value(n_intervals)

>>> df.columns
RangeIndex(start=0, stop=4, step=1)

# inside update_graph_2 callback
res1 = get_value_analyze(n_intervals)
>>> res1.columns
Index(
    [
        "bid_open",
        "bid_close",
        "tiks",
        "ask_open",
        "ask_close",
        "bid_min",
        "bid_max",
        "ask_min",
        "ask_max",
        "qvant",
        "sred",
        "skew",
        ">0",
        "=0",
        "<0",
    ],
    dtype="object",
)

This explains why the way you're passing data to graph in the first callback does work, since 0 and 1 exist in the index.

So in the second callback instead of passing in res[0], res[1], res[2], etc... pass in a column that exists in the index like res["bid_open"].