如何在Python中创建甘特图(使用plotly),包括持续时间为0天的任务(任务的开始和结束日期是同一日期)

问题描述 投票:0回答:1

我正在尝试用 Python 创建甘特图。我必须包含在图表中的一些任务的持续时间为 0 天,这意味着它们必须在同一天完成。

我尝试过在网上找到的这段代码,它用plotly创建了一个基本的甘特图:

df = pd.DataFrame([
    dict(Task="1", Start='2023-03-15', End='2023-03-15'),
    dict(Task="2", Start='2023-03-03', End='2023-03-10'),
    dict(Task="3", Start='2023-03-10', End='2023-03-15'),
])

print(df)

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

它适用于持续时间至少为 1 天的任务(例如任务 2 和 3)。但是,必须在同一天完成的任务(例如上例中的任务 1)在绘制后不会显示在甘特图中。生成的图表仅包含任务 2 和 3。任务 1 的标签旁边的空间保持空白。

有没有办法在与任务 2 和 3 相同的甘特图中显示任务 1(以及必须在同一天完成的其他任务)?

甘特图不一定是用 Plotly 创建的。也可以与 Matplotlib 一起使用。任何效果最好、最简单、最有用的选择。

感谢您的帮助!!

python matplotlib plotly gantt-chart
1个回答
0
投票

下面的示例使用

matplotlib
提供了类似的功能。当它发现任务的持续时间为 0 天时,它会为其分配一个较小的持续时间(0.1 天),以便它显示。您可以根据需要进行调整。

输出:

import pandas as pd
from matplotlib import patches
import matplotlib.pyplot as plt
import numpy as np

import matplotlib.dates as mdates

#
# Example data
#

#Original data
df = pd.DataFrame(
    {'Task': ['1', '2', '3'],
     'Start': ['2023-03-15', '2023-03-03', '2023-03-10'],
     'End': ['2023-03-15', '2023-03-10', '2023-03-15'],
     }
)

#Conver to datetime, as we'll do some simple arithmetic between dates
for date_col in ['Start', 'End']:
    df[date_col] = pd.to_datetime(df[date_col], format='%Y-%m-%d')
df

#
# Create plot
#
height = 0.9

f, ax = plt.subplots(figsize=(10, 6))
for idx in range(len(df)):
    y0 = (idx + 1) - height / 2
    x0 = df.iloc[idx].Start
    width = df.iloc[idx].End - x0
    if not width:
         width = pd.Timedelta(days=0.1)
    ax.add_patch( patches.Rectangle((x0, y0), width, height) )
    ax.hlines(y0 + height / 2,
              xmin=df.Start.min(),
              xmax=x0,
              color='k', linestyles=':', linewidth=0.5)

#DateFormatter required as we're building the plot using patches,
#rather than supplying entire series    
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
ax.xaxis.set_major_locator(mdates.DayLocator())
ax.set_xticklabels(ax.get_xticklabels(), rotation=30)

ax.set_xlabel('Date')
ax.set_ylabel('Task')
ax.set_yticks(range(1, len(df) + 1))
ax.set_yticklabels(df.Task)
plt.show()
© www.soinside.com 2019 - 2024. All rights reserved.