Not able to show px.timeline on Dashboard

Hello, I am trying to add a px.timeline to my dashboard with callback function in order to update the timeline based on filtering. However, I am not really familiar with the callbacks with px graphs and it does not show on my dashboard even though I think I correctly assign the callback functions. Here is part of my code (I did not put irrelevant part):

#----------App layout----------------------------------------------------------------------

app = dash.Dash(external_stylesheets=[dbc.themes.CYBORG])

app.layout = dbc.Container([
  
    html.Div([

        html.H2('Timelines', className="second-section-title"),

        dcc.Graph(id='timeline')

        ]),

    ])


#----------Callback for timeline graphs------------------------------------------------------------

@app.callback(

    [Output('timeline', 'figure')],

    [Input('input_subject','value')]

)

def update_timeline_graph(input_subject):

    # when there is no subject chosen

    if input_subject is None:

        dff = timeline_data

    else:

        dff = timeline_data[timeline_data == input_subject]

       

    timeline_graph = px.timeline(dff,

                                 x_start="Start",

                                 x_end="End",

                                 y="Subject",

                                 color='Type')

   

    timeline_graph.update_xaxes(tickformat="%H:%M:%S",

                                tickformatstops=[dict(dtickrange=[1800000, 10800000], value="%H:%M")])

   

    timeline_graph.update_yaxes(categoryorder="category ascending")

   

    timeline_graph.update_layout({'plot_bgcolor': 'rgba(0, 0, 0, 0)',

                                  'paper_bgcolor': 'rgba(0, 0, 0, 0)'})

   

    return (timeline_graph)

I don’t not really know how it is wrong since I followed the examples I found online

HI @yunyihuang
don’t worry about updating_axes and yaxes or making the graph pretty for now. Let’s focus on getting the graph to show up.
In the callback you declare an Input that refers to a component with the ID - ‘input_subject’. Where is that component? I can’t see it in the layout.

Also, can you provide example data so we can reproduce this code/problem on our computers. Here are some Plotly datasets.

Ah, sorry, did not notice that when removing some irrelevant code. The main problem for me is that when I put the dcc.Graph(id=“timeline”) in HTML, it only shows a regular empty grid graph instead of a plotly express graph.

Here is the part where I set up the input:

#code

dcc.Dropdown(id='input_subject',

                 #className="dropdown-menu",

                 options=[{'label': x, 'value': x} for x in df["Subject"].unique()],

                 style={"width": "100%"},

                 placeholder = 'All Data',

                 searchable=False,

                 clearable=True)

It is a dropdown menu.

Here is the data I have: timeline_data.

I can show you the full code if it is needed, it’s only about 180 lines.

hi @yunyihuang
the main problem was that you put Output and Input in []. They don’t need to go inside a list.
Some subjects had the same start and end time. I’m sure there is a way to plot your data by playing around with Pandas and datetime type. However, to show you a demo of how this plot works, I changed F1501 to have different start and end days in the data.

from dash import Dash, dcc, html, Input , Output
import plotly.express as px
import dash_bootstrap_components as dbc
import pandas as pd

df = pd.read_csv("timeline_data.xlsx - Sheet1.csv")
df["Start"] = pd.to_datetime(df["Start"])
df["Start"] = df["Start"].dt.strftime("%Y-%m-%d")
df["End"] = pd.to_datetime(df["End"])
df["End"] = df["End"].dt.strftime("%Y-%m-%d")

for x in df["End"][:5]:
    print(x)
    print(type(x))
# exit()

# ----------App layout----------------------------------------------------------------------

app = Dash(external_stylesheets=[dbc.themes.CYBORG])

app.layout = dbc.Container([

    html.Div([

        html.H2('Timelines', className="second-section-title"),
        dcc.Dropdown(id='input_subject',
                         #className="dropdown-menu",
                         options=[{'label': x, 'value': x} for x in df["Subject"].unique()],
                         style={"width": "100%"},
                         placeholder = 'All Data',
                         searchable=False,
                         value="F1501",
                         clearable=True),
        dcc.Graph(id='timeline')

    ]),

])


# ----------Callback for timeline graphs------------------------------------------------------------

@app.callback(

    Output('timeline', 'figure'),

    Input('input_subject', 'value')

)
def update_timeline_graph(input_subject):
    print(input_subject)

    if input_subject is None:

        dff = df.copy()

    else:

        dff = df[df["Subject"]==input_subject]
        print(input_subject)
        print(dff)

    timeline_graph = px.timeline(dff,

                                 x_start="Start",

                                 x_end="End",

                                 y="Type",

                                 color='Subject')

    # timeline_graph.update_xaxes(tickformat="%H:%M:%S",
    #
    #                             tickformatstops=[dict(dtickrange=[1800000, 10800000], value="%H:%M")])
    #
    # timeline_graph.update_yaxes(categoryorder="category ascending")
    #
    # timeline_graph.update_layout({'plot_bgcolor': 'rgba(0, 0, 0, 0)',
    #
    #                               'paper_bgcolor': 'rgba(0, 0, 0, 0)'})

    return timeline_graph


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

Hey Adam, thank you so much. And you are right, the brackets were the reason and I can now see my graph!
The data only has the time when the action happened (only start time), I don’t have the end time so basically what I did was to add a 20-seconds interval in order to actually show something on the timeline. There are overlaps, but it’s fine for me at this point. Thanks again and I will watch more of your tutorials on YouTube :grin:

1 Like