能否在 Jupyter Notebook Widget 中使用/复制 Plotly 时间线?

问题描述

情节的 plotly.express.timeline 非常棒,但它创造了自己的形象。似乎我需要将此视觉效果嵌入到 figureWidget 中,以使其与 Jupyter Notebook 中的布局配合得很好。因此,我尝试使用构建 px.timeline() 的 plotly.graph_objects.Bar() 重新创建绘图。

不幸的是,我不知道如何实现这一点。似乎条形的值被添加到不用作绝对位置的“基本”向量(作为相对值)。 Plotly 似乎不理解 datetime.timedelta() 对象。打印时间线()图形版本将值显示一个浮点值数组,不清楚它们是如何计算的。我试过简单地复制它们,但这最终导致认为 x 轴不是日期时间轴。

欢迎提供任何线索。如何使用 Box() 绘制适当的图形,或者如何在笔记本中嵌入/动画/布局 px.timeline() 图形。

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime

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

# working plotly express figure:
pxfig = px.timeline(df,x_start="Start",x_end="Finish",y="Task")
pxfig.show() # looks great

# broken bar figure:
plainfig = go.figure()
plainfig.add_bar(base=df['Start'],#                 x=pxfig.data[0].x,# this breaks the axis as they are not of type datetime.
#                 x=df['Finish']-df['Start'],# this doesn't produce the right plot
                 x=df['Finish'],# these appear to be relative to base,not absolute
                 y=df['Task'],orientation='h')

plainfig.show()

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

TimelinePlot

BoxPlot

figure({
    'data': [{'alignmentgroup': 'True','base': array([datetime.datetime(2009,0),datetime.datetime(2009,20,0)],dtype=object),'x': array([1.01088e+10,6.13440e+09,6.22080e+09]),'xaxis': 'x','y': array(['one','two','three'],'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','title': {'text': 'Task'}}}
})
figure({
    'data': [{'base': array([datetime.datetime(2009,'orientation': 'h','type': 'bar','x': array([datetime.datetime(2009,28,15,30,dtype=object)}],'layout': {'template': '...'}
})

解决方法

我无法回答如何将时间线嵌入到 FigureWidget 中,但我想我已经解决了您最初的问题,即让时间线与 jupyter 笔记本布局完美配合。我猜您希望能够以交互方式更新时间线?

我通过将 px.timeline 生成的图形嵌入到输出小部件中来解决这个问题。然后每当我需要更新图形时(例如从按钮回调),我只需清除输出小部件中的输出,创建一个新的时间线图形并显示该新图形。这不是最优雅的做事方式,但可以完成工作。

import ipywidgets as widgets
from IPython.display import display,clear_output
import pandas as pd
import plotly.express as px
from datetime import datetime

output = widgets.Output()

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

updated_df = pd.DataFrame([
    dict(Task="one",30)),dict(Task="four",10,10))
])

# display the original timeline figure
pxfig = px.timeline(df,x_start="Start",x_end="Finish",y="Task")
with output:
    display(pxfig)

# create a button which when pressed will update the timeline figure
button = widgets.Button(description='update figure')
def on_click(button):
    with output:
        clear_output()
        new_pxfig = px.timeline(updated_df,y="Task")
        display(new_pxfig)
button.on_click(on_click)

display(button)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...