multiple chained callbacks in plotly (date range picker)

Viewed 155

I have a dictionary, which contains of 3 dataframes (columns are identical), two dropdowns and one date range picker. First dropdown to choose the dataframe, the second to choose the columns. I have implemented 2 chained callbacks for dropdowns and now I want to create a third chained DatePickerRange which gives the Date through DatePickerRange. So in steps, first we select the dataframe, the filtered list of columns appears for that dataframe and as a next step, I want the DatePickerRange to get updated with the min and max Date values of that dataframes' column (date).

I tried to do something on my own but it doesn't work, my major doubts are I can't find a way to fill in start_date, end_date and I do need a third @app.callback but I don't know how to further do that. Thank you in advance. Here's the code:

import pandas as pd

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objects as go
from dash.dependencies import Input, Output, State


import urllib.request
import dash
import datetime as dt
import pandas as pd
from dash.dependencies import Input, Output, State, ClientsideFunction
import dash_core_components as dcc
import dash_html_components as html

import dash_bootstrap_components as dbc
import plotly      
import plotly.express as px
import pandas as pd    

import requests
from datetime import datetime
import plotly.graph_objects as go

df1 = {'date': ['2021-07-17 04:00:03', '2021-07-18 06:02:25', '2021-07-18 06:02:25'], 'prices': [31370, 35370, 32370]}
df1 = pd.DataFrame(data=df1)

df2 = {'date': ['2021-07-17 04:10:03', '2021-07-18 06:27:25', '2021-07-18 09:02:25'], 'prices': [1370, 8370, 2370]}
df2 = pd.DataFrame(data=df2)

df3 = {'date': ['2021-07-18 05:10:08', '2021-07-19 06:27:25', '2021-07-19 09:02:25'], 'prices': [24, 58, 123]}
df3 = pd.DataFrame(data=df3)

dict_main = {'df1': df1, 'df2': df2, 'df3': df3}


#----------------------------------------------------------------------

app = dash.Dash(__name__)
server = app.server

rpm = list(dict_main.keys())
channels = dict_main[rpm[0]]

for speed in rpm:
    start_date = dict_main[speed]['date'][0]
    end_date = dict_main[speed]['date'].to_list()[-1]

for speed in rpm:
    start_date = dict_main[speed]['date'][0]
    end_date = dict_main[speed]['date'].to_list()[-1]

app.layout = html.Div(
    [
        html.Div([
        dcc.Dropdown(
            id='rpm-dropdown',
            options=[{'label':speed, 'value':speed} for speed in rpm],
            value=list(dict_main.keys())[0],
            searchable=True
            ),
            ],style={'width': '20%', 'display': 'inline-block'}),
        html.Div([
        dcc.Dropdown(
            id='channel-dropdown',
            multi=True,
            ),
            ],style={'width': '20%', 'display': 'inline-block'}
        ),
        

                
                        html.Div([
                            dcc.DatePickerRange(
                            id = 'daterange',
                            start_date = start_date,
                          
                            end_date = end_date
        
                             ),
            ], style={'width': '98%', 'display': 'inline-block'}
        ),
                
        html.Div([
            dcc.Graph(
                id='Main-Graph'
            ),
            ], style={'width': '98%', 'display': 'inline-block'}
        )
    ]
)




@app.callback(
    Output('channel-dropdown', 'options'),
    [Input('rpm-dropdown', 'value')])
def update_date_dropdown(speed):

    return [{'label': i, 'value': i} for i in dict_main[speed].drop(columns = 'date')]   


@app.callback(
    Output('Main-Graph', 'figure'),
    [Input('channel-dropdown', 'value')],
    [State('rpm-dropdown', 'value'),
     State('daterange', 'start_date'),
     State('daterange', 'end_date')])
def updateGraph(channels, test, start_date, end_date):
    for speed in rpm:
        dff = dict_main[speed]
    dff = dff[(dff['date'] > dict_main[speed]['date'][0]) & (dff['date'] < dict_main[speed]['date'].to_list()[-1])]

    if channels:
        return go.Figure(data=[go.Scatter(x=dict_main[test]['date'], y=dict_main[test][i], name=i) for i in channels])
    else:
        return go.Figure(data=[])

if __name__ == '__main__':
    app.run_server(port =8050)
0 Answers
Related