?
?
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()