如何绘制含并行子任务的Gantt图?求Plotly实现及替代方案
实现同一Y轴任务项的并行子任务Gantt图
一、Plotly实现方案
核心思路是给同一主任务下的并行子任务设置相同的Task值,通过额外字段区分不同子任务,再用颜色映射实现视觉区分。
修改后的代码示例:
import plotly.express as px import pandas as pd df = pd.DataFrame([ # Job A的两个并行子任务 dict(Task="Job A", SubTask="子任务1", Start='2009-01-01', Finish='2009-01-20'), dict(Task="Job A", SubTask="子任务2", Start='2009-01-10', Finish='2009-02-28'), # 原有任务 dict(Task="Job B", SubTask="主任务", Start='2009-03-05', Finish='2009-04-15'), dict(Task="Job C", SubTask="主任务", Start='2009-02-20', Finish='2009-05-30') ]) # 生成时间线图,用SubTask区分颜色,自定义颜色映射 fig = px.timeline(df, x_start="Start", x_end="Finish", y="Task", color="SubTask", color_discrete_map={"子任务1": "red", "子任务2": "green", "主任务": "#888888"}) # 反转Y轴,让任务从上到下排列 fig.update_yaxes(autorange="reversed") # 调整条形宽度,避免并行子任务过度重叠 fig.update_traces(width=0.4) fig.show()
说明:
- 同一
Task值的子任务会自动放在Y轴的同一行,实现并行显示 - 通过
color_discrete_map可以精准指定每个子任务的颜色 - 调整
width参数可控制条形宽度,优化并行子任务的展示效果
二、非Plotly工具方案
1. Matplotlib(Python)
用水平条形图模拟Gantt图,手动计算子任务的时长和起始位置,在同一Y轴坐标绘制多个条形:
import matplotlib.pyplot as plt import pandas as pd from datetime import datetime df = pd.DataFrame([ {"Task": "Job A", "SubTask": "子任务1", "Start": '2009-01-01', "Finish": '2009-01-20', "Color": "red"}, {"Task": "Job A", "SubTask": "子任务2", "Start": '2009-01-10', "Finish": '2009-02-28', "Color": "green"}, {"Task": "Job B", "SubTask": "主任务", "Start": '2009-03-05', "Finish": '2009-04-15', "Color": "blue"}, ]) # 转换日期为数值格式,方便计算时长 df['Start_num'] = df['Start'].apply(lambda x: datetime.strptime(x, '%Y-%m-%d').toordinal()) df['Finish_num'] = df['Finish'].apply(lambda x: datetime.strptime(x, '%Y-%m-%d').toordinal()) df['Duration'] = df['Finish_num'] - df['Start_num'] # 给每个主任务分配Y轴坐标 task_y = {"Job A": 0, "Job B": 1} plt.figure(figsize=(10, 4)) for _, row in df.iterrows(): plt.barh(task_y[row['Task']], row['Duration'], left=row['Start_num'], color=row['Color'], height=0.3) # 设置Y轴标签 plt.yticks(list(task_y.values()), list(task_y.keys())) # 转换X轴为日期格式 plt.xticks(rotation=45) plt.gca().xaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: datetime.fromordinal(int(x)).strftime('%Y-%m-%d'))) plt.tight_layout() plt.show()
2. Mermaid(文本绘图)
纯文本语法快速生成Gantt图,原生支持并行任务定义:
gantt dateFormat YYYY-MM-DD title 并行子任务Gantt图 section Job A 子任务1 : active, red, 2009-01-01, 20d 子任务2 : green, 2009-01-10, 50d section Job B 主任务 : blue, 2009-03-05, 42d section Job C 主任务 : orange, 2009-02-20, 100d
3. Excel
无需编程,通过堆叠条形图实现:
- 将主任务作为Y轴标签,每个并行子任务设为单独的数据列
- 设置条形图为水平堆叠样式,调整每个系列的颜色和起始日期(X轴用日期格式)
内容的提问来源于stack exchange,提问作者Matheus Diogenes Andrade
相关产品推荐
相关产品推荐

