Analytics_TM
Analytics_TM

Reputation: 523

Python Dash: Function should not run when n_clicks < 0 and defined in a call back

I am working on plotly dash app. I have an almost working example. The only thing that is not working is that I am not able to restrict the functions defined in the callbacks not to run when the page loads.

I have tried add checks for the n_clicks inside the callback however it doesnt seem to be working. It runs the function without the clicks as well

Below is the code for the dash

from datetime import date
import base64
import dash
import plotly
import dash

from dash.dependencies import Input, Output, State
from plotly.graph_objs import *
from datetime import datetime as dt
import dash_html_components as html
import dash_core_components as dcc

import flask
import pandas as pd

server = flask.Flask('app')

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash('app', server=server, external_stylesheets=external_stylesheets)



app.layout = html.Div(style={'backgroundColor': '#EFEAEA', 'margin': '0px', 'padding': '0px'}, children=[
    html.Div([
        html.Div([
            html.Img(src='data:image/png;base64,{}'.format(encoded_image.decode()),
                 style={'width': '200px', 'height': '100px', 'display': 'inline-block', 'float': 'left', 'padding-left': '5px', 'padding-top': '5px'})
        ]),
        html.Div([
            html.Div([
                html.Div([
                    dcc.Dropdown(
                        id='demographics',
                        options=[
                            {'label': 'All 18-49', 'value': '18_39'},
                            {'label': 'Female 25-54', 'value': '25_54 F'},
                            {'label': 'All 25-54', 'value': '25-54'},
                        ],
                        placeholder="Select Demographics",
                    )
                ],
                    style={'width': '30.5%', 'display': 'inline-block', 'padding-right': '10px'}),
                html.Div([
                    dcc.DatePickerRange(
                        id='my-date-picker-range',
                        start_date_placeholder_text="Select a Start Date",
                        end_date_placeholder_text="Select an End Date",
                        min_date_allowed=dt(2018, 1, 1),
                        max_date_allowed=dt(2050, 12, 31),
                        initial_visible_month=dt(2019, 1, 2),
                        style={'width': '600', 'display': 'inline-block', 'padding-right': '10px'}
                    ),
                    html.Div(id='output-container-date-picker-range')
                ],
                    style={'width': '30.3%', 'display': 'inline-block', 'padding-right': '10px', 'position': 'relative'})

            ],
                style={
                'backgroundColor': '#EFEAEA',
                'padding': '5px 10px'}),
            html.Div([
                html.Div([
                    dcc.Dropdown(
                        id='Horsepower',
                        options=[
                            {'label': '200', 'value': 'two_hundred'},
                            {'label': '250', 'value': 'two_hundred_fifty'},
                            {'label': '300', 'value': 'three_hundred'},
                            {'label': '350', 'value': 'three_hundred_fifty'},
                            {'label': '400', 'value': 'four_hundred'}
                        ],
                        placeholder="Select TARP",
                    )
                ],
                    style={'width': '20%', 'display': 'inline-block', 'padding-right': '10px'}),
                html.Div([
                    dcc.Dropdown(
                        id='Kilometers',
                        options=[
                            {'label': '250,000', 'value': 250000, 'type': 'number'},
                            {'label': '500,000', ''value': 500000, 'type': 'number'},
                            {'label': '750,000', 'value': 750000, 'type': 'number'},
                            {'label': '1,000,000', 'value': 1000000, 'type': 'number'},
                        ],
                        placeholder="Select Impressions",
                    )
                ],
                    style={'width': '20%', 'display': 'inline-block', 'padding-right': '10px'}),
                html.Div([
                    dcc.Dropdown(
                        id='Speed',
                        options=[
                            {'label': 'Low', 'value': 50, 'type': 'number'},
                            {'label': 'Average', 'value': 100, 'type': 'number'},
                            {'label': 'High', 'value': 150, 'type': 'number'},
                        ],
                        placeholder="Select Frequency",
                    )
                ],
                    style={'width': '20%', 'display': 'inline-block', 'padding-right': '10px'}),
                html.Div([
                    html.Button('Submit', id='submit_button', type='submit', n_clicks=1,
                                style={'width': '100px', 'height': '34.5px', 'margin-bottom': '8px',
                                       'border-radius': '4px', 'display': 'inline-block', 'background-color': '#2D91C3', 'color': 'white'})
                ],
                    style={'display': 'inline-block', 'padding-bottom': '20px', 'verticalAlign': 'middle'}),
            ], style={
                'backgroundColor': '#EFEAEA',
                'padding': '5px'})
            ], style={'position': 'relative', 'left': '250px'})
        ]),

    html.Div([
        html.Div([
            dcc.Graph(id='example-graph', config={'modeBarButtonsToRemove': ['pan2d', 'lasso2d', 'sendDataToCloud',
                                                                             'select2d', 'autoScale2d', 'resetScale2d',
                                                                             'toggleSpikelines',
                                                                             'hoverClosestCartesian']})
        ],
            style={'width': '49.3%', 'display': 'inline-block', 'border': 'thin grey solid',  'margin-left': '5px',
                   'margin-right': '2.5px', 'margin-top': '5px', 'margin-bottom': '2.5px'}),
        html.Div([
            dcc.Graph(id='example-graph1')
        ],
            style={'width': '49.3%', 'display': 'inline-block', 'border': 'thin grey solid', 'margin-left': '2.5px',
                   'margin-right': '5px', 'margin-top': '5px', 'margin-bottom': '2.5px', 'backgroundColor': '#EFEAEA'})
        ], style={'backgroundColor': '#EFEAEA'}),
    html.Div([
        dcc.Graph(id='graph1')
    ],
        style={'width': '99.2%', 'height': '120%', 'display': 'inline-block', 'border': 'thin grey solid', 'margin-left': '2.5px',
               'margin-right': '5px', 'margin-top': '5px', 'margin-bottom': '2.5px', 'backgroundColor': '#EFEAEA'})
    ])


@app.callback(Output('example-graph1', 'figure'),
              [Input('submit_button', 'n_clicks')],
              [State('my-date-picker-range', 'start_date'),
               State('my-date-picker-range', 'end_date')])

def update_graph(n_clicks, start_date,  end_date):
    if n_clicks > 0:
        df = df_new
        start_date_temp = dt.strptime(start_date, '%Y-%m-%d')
        end_date_temp = dt.strptime(end_date, '%Y-%m-%d')
        start_date_new = start_date_temp.replace(start_date_temp.year - 1)
        end_date_new = end_date_temp.replace(end_date_temp.year - 1)
        end_date_string = end_date_new.strftime('%Y-%m-%d')
        start_date_string = start_date_new.strftime('%Y-%m-%d')
        mask = (df['Date'] >= start_date_string) & (df['Date'] <= end_date_string)
        filtered_df = df.loc[mask]
        trace = Scatter(
            y=filtered_df['Weights'],
            x=filtered_df['Date'],
            line=plotly.graph_objs.scatter.Line(
                color='#42C4F7'
            ),
            hoverinfo='skip',
            error_y=plotly.graph_objs.scatter.ErrorY(
                type='data',
                array=filtered_df['Gender'],
                thickness=1.5,
                width=2,
                color='#B4E8FC'
            ),
            mode='lines'
        )
        layout1 = Layout(
            height=450,
            xaxis=dict(
                showgrid=False,
                showline=False,
                zeroline=False,
                fixedrange=True,
                title='Time Elapsed (sec)'
            ),
            yaxis=dict(
                showline=False,
                fixedrange=True,
                zeroline=False,

            ),
            margin=plotly.graph_objs.layout.Margin(
                t=45,
                l=50,
                r=50
            )
        )

        return Figure(data=[trace], layout=layout1)
    else:
        return {"I am the boss"}

The reason I presume the n_clicks checks is not working because I get the following error

TypeError: strptime() argument 1 must be str, not None

I believe the error is because of the below code inside the function as the first time the page loads start_date would be none type.

start_date_temp = dt.strptime(start_date, '%Y-%m-%d')

Can some one please help to resolve the issue. What I expect that when the page loads the call back function should not run.

Thanks a lot in advance !!

Upvotes: 2

Views: 3865

Answers (1)

coralvanda
coralvanda

Reputation: 6616

Here is your problem:

html.Button('Submit', id='submit_button', type='submit', n_clicks=1,

You've preset n_clicks to have a value. Just remove that n_clicks=1 part, and it will load the page as None. You will then need to check n_clicks like this (or similar):

if n_clicks is not None and n_clicks > 0:

It worked for me, and ran until it broke with my example df.

Upvotes: 2

Related Questions