Search code examples
pythondashboardplotly-dash

Date slider with Plotly Dash does not work


I am trying to build a dash app with a datetime slider, but the following code does not work - the url displays "Error loading layout". Is there something wrong with my code, or are there any tricks needed to build a slider on datetime objects? Reproducible code follows:

import dash
import dash_core_components as dcc
import dash_html_components as html
import datetime

base = datetime.datetime.today()
date_list = [base - datetime.timedelta(days=x) for x in range(0, 10)]

app = dash.Dash()

app.layout = html.Div([
    html.Label('Slider'),
    dcc.RangeSlider(min=min(date_list), 
                    max=max(date_list), 
                    value=min(date_list))
    ])

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

Solution

  • Plotly-Dash does currently not support datetime objects.

    A solution for you problem is to described in my answer to an other question Plotly datetime


    One possible solution is to use two different arguments at the initialization:

    • value
    • marks

    Example by using pandas for timestamp generation:

    Needed imports:

    import pandas as pd
    import time
    

    Some needed functions:

    daterange = pd.date_range(start='2017',end='2018',freq='W')
    
    def unixTimeMillis(dt):
        ''' Convert datetime to unix timestamp '''
        return int(time.mktime(dt.timetuple()))
    
    def unixToDatetime(unix):
        ''' Convert unix timestamp to datetime. '''
        return pd.to_datetime(unix,unit='s')
    
    def getMarks(start, end, Nth=100):
        ''' Returns the marks for labeling. 
            Every Nth value will be used.
        '''
    
        result = {}
        for i, date in enumerate(daterange):
            if(i%Nth == 1):
                # Append value to dict
                result[unixTimeMillis(date)] = str(date.strftime('%Y-%m-%d'))
    
        return result
    

    For the RangeSlider object you can initialize it like this:

    dcc.RangeSlider(
                    id='year_slider',
                    min = unixTimeMillis(daterange.min()),
                    max = unixTimeMillis(daterange.max()),
                    value = [unixTimeMillis(daterange.min()),
                             unixTimeMillis(daterange.max())],
                    marks=getMarks(daterange.min(),
                                daterange.max())
                )