2

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

xxxHEKETOSxxx
  • 57
  • 1
  • 9
  • What is the exact error message you receive? – bk_ Jun 28 '21 at 13:00
  • 1
    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. – 5eb Jun 28 '21 at 14:03
  • My memory may not be accurate, but isn't a list unnecessary in a callback function? – r-beginners Jun 28 '21 at 14:20
  • added res1 output – xxxHEKETOSxxx Jun 28 '21 at 14:35
  • found one error, an extra sibvol in the def get_value_analyze (n_intervals) function however, the same callback error still comes out – xxxHEKETOSxxx Jun 28 '21 at 15:02
  • If you provide a minimal but complete example that people here can run that would help in getting an answer that solves your problem. Sharing the output of `res1` is nice, but better would be, like I mentioned earlier, to put some insert statements / database dump that allows us to run the app from start to finish. Otherwise it's just guessing what the problem is. – 5eb Jul 01 '21 at 13:26
  • updated the question: added output from df – xxxHEKETOSxxx Jul 01 '21 at 14:40
  • from the first dataframe the chart is drawn, from the second the callback does not work – xxxHEKETOSxxx Jul 01 '21 at 14:42
  • I meant that you could put the output of something like this in the question: `sqlite3 base_eurousd.db .dump`. Using that we can recreate your database. What I will say is that I think you can avoid a lot of trouble trying to select columns by number and select columns by name instead, see [this post](https://stackoverflow.com/questions/7831371/is-there-a-way-to-get-a-list-of-column-names-in-sqlite) for how to get column names from query. – 5eb Jul 01 '21 at 15:27
  • 1
    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 callback – xxxHEKETOSxxx Jul 01 '21 at 17:04

1 Answers1

1

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"].

5eb
  • 14,798
  • 5
  • 21
  • 65
  • res1 is a grouping from res, respectively, the very first column in it must be an index ... However, from print (res1.index) it outputs the following: dtype='datetime64[ns]', name=0, length=529, freq='T' – xxxHEKETOSxxx Jun 28 '21 at 23:52
  • generally wanted to display data in x coordinates, where x is the position in time, y is the rest of the data in time – xxxHEKETOSxxx Jun 28 '21 at 23:53
  • can't figure out how to access the index to pass parameters to plotly dash – xxxHEKETOSxxx Jul 01 '21 at 03:28
  • if use res1 = res1.reset_index() res1[0] = pd.to_datetime(res1[0]).astype('int64') / 10 ** 9 - data type changes .. The error remains. This means that this is not the error – xxxHEKETOSxxx Jul 01 '21 at 09:23