我正在尝试用 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 一起使用。任何效果最好、最简单、最有用的选择。
感谢您的帮助!!
下面的示例使用
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()