带有整数 xaxis 的甘特图的 Plotly Express 时间线? 答案:情节详情:完整代码:

问题描述

我正在使用 plotly express 时间线来按照以下示例生成甘特图:https://medium.com/dev-genius/gantt-charts-in-python-with-plotly-e7213f932f1e

它会自动设置 x 轴以使用日期,但我实际上只想使用整数(即项目启动 +1、项目启动 +6 等)。

有没有办法让时间线图不使用 xaxis 的日期?

如果我尝试使用整数,它会将它们视为毫秒。

解决方法

答案:

是的,这是可能的!只需将整数作为开始和结束“日期”,计算它们之间的差异 (delta),然后对您的 fig 进行这些更改:

fig.layout.xaxis.type = 'linear'
fig.data[0].x = df.delta.tolist()

情节

enter image description here

详情:

实际上有一种方法可以实现这一点,尽管 docs 声明:

px.timeline 函数默认设置 X 轴为 type=date,因此它可以像任何时间序列图表一样进行配置。

因此 px.timeline() 中的所有其他功能似乎都围绕这一事实。但是,如果您只是忽略它并使用整数作为 StartFinish 的值,那么您可以调整一些属性以获得您想要的。您只需要计算每个 StartStop 之间的差异。例如像这样:

df = pd.DataFrame([
    dict(Task="Job A",Start=1,Finish=4),dict(Task="Job B",Start=2,Finish=6),dict(Task="Job C",Start=3,Finish=10)
])
df['delta'] = df['Finish'] - df['Start']

然后进一步调整:

fig.layout.xaxis.type = 'linear'
fig.data[0].x = df.delta.tolist()

完整代码:

import plotly.express as px
import pandas as pd

df = pd.DataFrame([
    dict(Task="Job A",Finish=10)
])
df['delta'] = df['Finish'] - df['Start']

fig = px.timeline(df,x_start="Start",x_end="Finish",y="Task")
fig.update_yaxes(autorange="reversed") 

fig.layout.xaxis.type = 'linear'
fig.data[0].x = df.delta.tolist()
f = fig.full_figure_for_development(warn=False)
fig.show()
,

我尝试了此处列出的其他答案,但如果我指定了 color,那将不起作用。如果我尝试,数据 fig.data 有多个 Bar 对象,我认为它不包含分配所有增量所需的数据。但是,我确实发现我可以使用monkeypatch plotly code 不将其转换为时间对象,并且得到了正确的结果:

import plotly.express as px
import pandas as pd

def my_process_dataframe_timeline(args):
    """
    Massage input for bar traces for px.timeline()
    """
    print("my method")
    args["is_timeline"] = True
    if args["x_start"] is None or args["x_end"] is None:
        raise ValueError("Both x_start and x_end are required")

    x_start = args["data_frame"][args["x_start"]]
    x_end = args["data_frame"][args["x_end"]]

    # note that we are not adding any columns to the data frame here,so no risk of overwrite
    args["data_frame"][args["x_end"]] = (x_end - x_start)
    args["x"] = args["x_end"]
    del args["x_end"]
    args["base"] = args["x_start"]
    del args["x_start"]
    return args
px._core.process_dataframe_timeline = my_process_dataframe_timeline

df = pd.DataFrame([
    dict(Task="Job A",Finish=4,color="1"),Finish=6,color="2"),Finish=10,color="1")
])
df['delta'] = df['Finish'] - df['Start']

fig = px.timeline(df,y="Task",color="color")
fig.update_yaxes(autorange="reversed") 

fig.layout.xaxis.type = 'linear'
fig.show()

显然不希望这样做......获得正式支持会很好。

相关问答

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