import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
from matplotlib import cm# 中文字体配置(必须放在所有绘图语句之前)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False# 时间矩阵数据
jobs = {'工件1': [31, 41, 25, 30],'工件2': [19, 55, 3, 34],'工件3': [23, 42, 27, 6],'工件4': [13, 22, 14, 13],'工件5': [33, 5, 57, 19]
}# 初始化变量
machines = ['机器1', '机器2', '机器3', '机器4']
order = list(jobs.keys())
current_time = {m: 0 for m in machines}# 使用专业色系(参考网页7)
colors = cm.get_cmap('viridis', len(jobs))(np.linspace(0, 1, len(jobs)))# 计算调度时间表
schedule = []
total_time = 0
for job in order:times = jobs[job]start_times = []end_times = []for i, (m, t) in enumerate(zip(machines, times)):start = max(current_time[m], end_times[-1] if i > 0 else 0)end = start + tstart_times.append(start)end_times.append(end)current_time[m] = endtotal_time = max(total_time, max(end_times))schedule.append({'job': job, 'start': start_times, 'end': end_times})# 创建动态甘特图
fig, ax = plt.subplots(figsize=(12, 6))
ax.set_xlabel('时间')
ax.set_ylabel('机器')
ax.set_yticks(range(len(machines)))
ax.set_yticklabels(machines)
ax.set_title(f'流水车间调度甘特图 | 合计用时:{total_time} 单位')# 动画初始化函数
def init():ax.set_xlim(0, total_time)return []# 动画更新函数(优化颜色绑定)
def update(frame):ax.clear()ax.set_yticks(range(len(machines)))ax.set_yticklabels(machines)current_total = 0for i, s in enumerate(schedule[:frame+1]):for m_idx in range(len(machines)):start = s['start'][m_idx]end = s['end'][m_idx]duration = end - startax.broken_barh([(start, duration)], (m_idx-0.4, 0.8),facecolors=colors[i],edgecolor='black',linewidth=0.5)current_total = max(current_total, end)# 动态创建图例句柄(参考网页6)handles = [plt.Rectangle((0,0),1,1, color=colors[i], ec='black') for i in range(frame+1)]ax.legend(handles, order[:frame+1], loc='upper right',title='加工序列',facecolor='#F0F0F0',edgecolor='black')ax.set_title(f'流水车间调度进度({frame+1}/{len(order)})| 当前用时:{current_total} | 总用时:{total_time}')return []# 生成动画(调慢播放速度)
ani = animation.FuncAnimation(fig, update, frames=len(order),interval=1500, # 每帧间隔1.5秒init_func=init, blit=True, repeat=False
)plt.show()