Can a timeline be created in a FigureWidget in Jupyter Notebook?

I am trying to draw a timeline inside a FigureWidget in a Jupyter Notebook. This apparently means I can’t use plotly.express.timeline as that creates its own figure. When trying to re-create the plot using Bar() (which timeline does under the hood) I cannot figure out how to get the desired results.

It appears that the values for the bars are added to the ‘base’ value not used as absolute positions (is there a way to change this?). Unfortunately, plotly Bar() does not appear to understand python datetime.timedelta() objects (see figure “Timedelta”)

Printing the timeline() figure version shows the values as an array of floating point values which it isn’t clear how they are computed. I’ve tried simply copying them, but this ends up with plotly thinking the x axis isn’t a datetime axis.

Any clue would be most welcome. Either how to use the Box() to draw the appropriate figure, or how to embed/animate/layout the px.timeline() figure in a Jupyter notebook.

df = pd.DataFrame([dict(Task="one", Start=datetime(2009,1,1), Finish=datetime(2009,4,28)),
               dict(Task="two", Start=datetime(2009,5,5), Finish=datetime(2009,7,15)),
               dict(Task="three", Start=datetime(2009,7,20), Finish=datetime(2009,9,30)) ])

# stand-alone plotly express figure that draws correctly shown as "Timeline"
pxfig = px.timeline(df, x_start="Start", x_end="Finish", y="Task")
pxfig.show()

# Broken bar figure (Timedelta)
plainfig = go.Figure()
plainfig.add_bar(base=df['Start'], y=df['Task'], orientation='h',
#                x=pxfig.data[0].x,    # makes axis not type datetime.
                x=df['Finish']-df['Start']) # plot oddly wrong Shown as "Timedelta"
plainfig.show()

# broken figure (Absolute)
plainfig2 = go.Figure()
plainfig2.add_bar(base=df['Start'], y=df['Task'], orientation='h',
                 x=df['Finish']) # Shown as "Absolute"
plainfig2.show()

# looking at the two shows interesting differences in the way the x data is stored
print(pxfig)
print(plainfig)

Printing results in:

Figure({
    'data': [{'alignmentgroup': 'True',
          'base': array([datetime.datetime(2009, 1, 1, 0, 0),
                         datetime.datetime(2009, 5, 5, 0, 0),
                         datetime.datetime(2009, 7, 20, 0, 0)], dtype=object),
          'x': array([1.01088e+10, 6.13440e+09, 6.22080e+09]),
          'xaxis': 'x',
          'y': array(['one', 'two', 'three'], dtype=object),
          'yaxis': 'y'}],
    'layout': {'barmode': 'overlay',
           'legend': {'tracegroupgap': 0},
           'margin': {'t': 60},
           'template': '...',
           'xaxis': {'anchor': 'y', 'domain': [0.0, 1.0], 'type': 'date'},
           'yaxis': {'anchor': 'x', 'domain': [0.0, 1.0], 'title': {'text': 'Task'}}}
})
Figure({
    'data': [{'base': array([datetime.datetime(2009, 1, 1, 0, 0),
                         datetime.datetime(2009, 5, 5, 0, 0),
                         datetime.datetime(2009, 7, 20, 0, 0)], dtype=object),
          'orientation': 'h',
          'type': 'bar',
          'x': array([datetime.datetime(2009, 4, 28, 0, 0),
                      datetime.datetime(2009, 7, 15, 0, 0),
                      datetime.datetime(2009, 9, 30, 0, 0)], dtype=object),
          'y': array(['one', 'two', 'three'], dtype=object)}],
    'layout': {'template': '...'}
})

It’s kind of late now, but I’ll reply in case someone is facing the same issue:
I also had a strangely plot when using bar-plot with timedelta. It seems to be an issue on ploty (see the GitHub issue). Plotly express timeline (px.timeline) seem to handle correctly. I managed to do the workaround by doing 2 things:

  • adding a type:“date” to the xaxis:
    fig[‘layout’][‘xaxis’].update(dict( type=“date” ))
  • dividing the timedelta by 1 million (seems that the time units are the problem here):
    x=(df[‘Finish’]-df[‘Start’])/1000000

Now I have a decent range and tick labels on the x axis