You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:基于Python自定义类数据绘制甘特图

基于Python类结构数据绘制甘特图

你可以通过以下步骤实现需求,核心是先将嵌套的类结构数据扁平化,再使用Matplotlib的barh方法绘制甘特图:

1. 补全类定义(添加构造方法)

原类仅有类型注解,无法直接创建实例,需补充__init__方法:

from typing import List, Any
import matplotlib.pyplot as plt

# 定义未分配标记(与你代码中的UNASSIGNED_FLAG一致)
UNASSIGNED_FLAG = -1

class Stage:
    def __init__(self, id: int):
        self.id = id
        self.production_equipment: List[ProductionEquipment] | None = []

class ProductionEquipment:
    def __init__(self, id: int, norm_mw: Any, stage: int):
        self.id = id
        self.norm_mw = norm_mw
        self.stage = stage
        self.production_tasks: List[ProductionTask] | None = []

class ProductionTask:
    def __init__(self, id: int, processingtime: int, duration: float, done: bool):
        self.id = id
        self.processingtime = processingtime
        self.duration = duration
        self.done = done
        self.start_time: int = UNASSIGNED_FLAG
        self.end_time: int = UNASSIGNED_FLAG
        self.production_equipment: Any = UNASSIGNED_FLAG
        self.stage: Any = UNASSIGNED_FLAG

2. 生成模拟数据(匹配你的3阶段2设备场景)

如果已有真实数据,可跳过此步骤,直接使用你的业务数据:

# 创建3个阶段,每个阶段2台设备,每台设备分配2个已排程任务
stages = []
for stage_id in range(1, 4):
    stage = Stage(stage_id)
    for eq_id in range(1, 3):
        equipment = ProductionEquipment(eq_id, 100, stage_id)
        # 任务1
        task1 = ProductionTask(id=eq_id*10+1, processingtime=5, duration=12.0, done=False)
        task1.start_time = 10 + (stage_id-1)*20 + (eq_id-1)*5
        task1.end_time = task1.start_time + int(task1.duration)
        task1.production_equipment = equipment
        task1.stage = stage_id
        
        # 任务2
        task2 = ProductionTask(id=eq_id*10+2, processingtime=5, duration=18.0, done=False)
        task2.start_time = task1.end_time + 3
        task2.end_time = task2.start_time + int(task2.duration)
        task2.production_equipment = equipment
        task2.stage = stage_id
        
        equipment.production_tasks.extend([task1, task2])
    stage.production_equipment.append(equipment)
    stages.append(stage)

3. 扁平化数据(提取绘图所需字段)

将嵌套的Stage->ProductionEquipment->ProductionTask结构展开,提取设备标签、任务起始时间、任务时长:

equipment_labels = []
task_starts = []
task_durations = []
task_colors = []

# 用于区分不同任务的颜色池
color_list = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b']

for stage in stages:
    for equipment in stage.production_equipment:
        # 生成易识别的设备标签,如"阶段1-设备1"
        eq_label = f"阶段{stage.id}-设备{equipment.id}"
        equipment_labels.append(eq_label)
        # 仅处理已分配的任务(排除start_time为UNASSIGNED_FLAG的任务)
        for idx, task in enumerate(equipment.production_tasks):
            if task.start_time != UNASSIGNED_FLAG:
                task_starts.append(task.start_time)
                task_durations.append(task.duration)
                task_colors.append(color_list[idx % len(color_list)])

4. 绘制甘特图

使用barh方法绘制,设置X轴范围为0-96时间步:

fig, ax = plt.subplots(figsize=(12, 6))

# barh参数说明:y轴位置为设备索引,宽度为任务时长,左边界为任务起始时间
y_positions = range(len(equipment_labels))
ax.barh(y_positions, task_durations, left=task_starts, color=task_colors, edgecolor='black')

# 设置轴标签与范围
ax.set_yticks(y_positions)
ax.set_yticklabels(equipment_labels)
ax.set_xlim(0, 96)
ax.set_xlabel("时间步")
ax.set_ylabel("设备")
ax.set_title("设备生产任务甘特图")

# 添加垂直网格线,便于查看时间节点
ax.grid(True, axis='x', linestyle='--', alpha=0.7)

# 调整布局,避免标签被截断
plt.tight_layout()
plt.show()

关键注意点

  • 若使用真实数据,需确保ProductionTask的start_time和end_time已正确赋值(不是UNASSIGNED_FLAG)
  • barh的left参数是实现甘特图的核心,它指定了每个任务的起始位置,而非默认的从Y轴开始

内容的提问来源于stack exchange,提问作者Margi Shah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 14:52:49