brb
brb

Reputation: 1179

Dependency issues with python's plotly and dash

I am trying to construct a dashboard in python using plotly and dash that will use a slider to change the range (x-axis) of a graph. The x-axis contains dates.

I am following the example for a slider on on plotly's website (https://dash.plot.ly/dash-core-components/rangeslider). The slider example works fine in my environment. When I replace the min, max values for the slider with the minimum and maximum date values in my dataframe as follows:

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
    dcc.RangeSlider(
        id='slider',
        min = df['date'].min(),
        max = df['date'].max()
    ),
    html.Div(id='slider-container')
])

my browser throws the following error: 'Error loading dependencies'. 'date' in my dataframe is a pandas._libs.tslibs.timestamps.Timestamp

I have uninstalled and reinstalled dash, dash-renderer, dash-html-components, dash-core-components and plotly as per https://github.com/plotly/dash/issues/82

Any suggestions on what is going wrong? The complete code for my example is:

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

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
    dcc.RangeSlider(
        id='slider',
        min = df['date'].min(),
        max = df['date'].max()
    ),
    html.Div(id='slider-container') ])


@app.callback(
    dash.dependencies.Output('slider-container', 'children'),
    [dash.dependencies.Input('slider', 'value')])
def update_output(value):
    return 'You have selected "{}"'.format(value)


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

And this works fine if slider values are set to:

    dcc.RangeSlider(
        id='slider',
        min=0,
        max=20,
        step=0.5,
        value=[5, 15]

Upvotes: 1

Views: 1817

Answers (1)

Shovalt
Shovalt

Reputation: 6766

It seems that RangeSlider can't work directly with Timestamp objects. You need to convert them into numerical (POSIX) timestamps to work with the slider, and convert them again into objects inside the callback function.

The following worked for me:

import dash
import dash_core_components as dcc
import dash_html_components as html
import numpy as np
import pandas as pd

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

# Demo dataframe with a 'date' column
df = pd.DataFrame({'date': pd.to_datetime(np.linspace(1500000000, 1550000000, 9), unit='s')})

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
    dcc.RangeSlider(
        id='slider',
        min=df['date'].min().timestamp(),
        max=df['date'].max().timestamp(),
        value=[df['date'].min().timestamp(), df['date'].max().timestamp()],
    ),
    html.Div(id='slider-container')
])


@app.callback(
    dash.dependencies.Output('slider-container', 'children'),
    [dash.dependencies.Input('slider', 'value')])
def update_output(value):
    if value:
        return 'You have selected "{}"'.format(list(pd.to_datetime(value, unit='s')))


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

Upvotes: 1

Related Questions