У меня есть код, который генерирует диаграмму Ганта, и я хотел бы добавить категориальное значение (значение фильтра) в виде текста / аннотации к графику (возможно, в качестве заголовка).
У меня есть два кадра данных, которые используются для построения диаграммы Ганта ниже. Один кадр данных представляет запланированное время для операций, а другой представляет фактическое время. Первоначально оба фрейма данных содержат данные для многих рабочих центров, но я отфильтрую их, чтобы с помощью этой команды отображались данные только для одного рабочего центра: df = df.loc[df1['Work center'] == '503AL302']
.
В моем коде я фильтрую оба фрейма данных по одному work center
и я хотел бы показать, что данные захватывают данные только для определенного рабочего места. В данном конкретном случае это «503AL302». Я не хочу вручную вводить рабочий центр в виде строки в заголовке, но хочу отобразить значение, используемое для фильтрации work centers
. В будущем я буду менять фильтры в зависимости от значения work center
и хочу, чтобы график автоматически отображал, какие данные рабочего центра представлены. Основная цель этого состоит в том, чтобы четко увидеть, какой рабочий центр выбран, это не обязательно заголовок или легенда.
Вот мой код, который генерирует диаграмму Ганта. Дайте мне знать, и я могу предоставить пример данных вместе с ним для тестирования:
import pandas as pd
from datetime import datetime
import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import math
import time
import matplotlib.patches as mpatches
df = pd.read_csv('zpp00141_new.csv')
df1 = pd.read_csv('sample_data1.csv')
df = df.loc[df['Work Center'] == '503AL302']
df1 = df1.loc[df1['Work center'] == '503AL302']
#convert times to number to calculate
def timestr_to_num(timestr):
return mdates.date2num(datetime.strptime('0' + timestr if timestr[1] == ':' else timestr, '%I:%M:%S %p'))
#gantt chart plotting
fig, ax = plt.subplots(figsize=(12.5, 6))
operations = pd.unique(df['Operation/Activity'])
#Declaring a colormap
cmap = plt.cm.get_cmap('plasma_r')
colors = [cmap(i/20) for i in range(20)]
#plot scheduled operations
for operation, color in zip(operations, colors):
for row in df[df['Operation/Activity'] == operation].itertuples():
left = timestr_to_num(row.start)
right = timestr_to_num(row.finish)
ax.barh(operation, left=left, width=right - left, height=1, color="#6ED06F", edgecolor = 'black', label = operation)
#plot "Actual" operations' times
operations1 = pd.unique(df1['Operation/Activity'])
for operation, color in zip(operations1, colors):
for row in df1[df1['Operation/Activity'] == operation].itertuples():
left = timestr_to_num(row.start)
right = timestr_to_num(row.finish)
ax.barh(operation, left=left, width=right - left, height=0.4, color='#33AFFF', edgecolor = 'black', label = operation)
#plt.legend()
#set x-axis limit
ax.set_xlim(timestr_to_num('06:00:00 AM'), timestr_to_num('4:30:00 PM'))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M')) # display ticks as hours and minutes
ax.xaxis.set_major_locator(mdates.HourLocator(interval=1)) # set a tick every hour
#set y and x labels
ax.set_xlabel('Time', fontsize = 'large')
ax.set_ylabel('Operation', fontsize = 'large')
plt.tight_layout()
ax.set_yticklabels(list(df['Operation/Activity'] + " - " + df['Operation short text'].astype(str)))
ax.tick_params(axis='both', which='major', labelsize=11)
#add a title to a plot
plt.title("Schedule", fontsize = 'x-large')
#convert "now" time to a certain format of hours:minutes:seconds am/pm and plot a vertical red line for the "Current time"
now = datetime.now()
now = now.strftime('%I:%M:%S %p')
plt.axvline(x=timestr_to_num(now),color='r', animated = True)
#adding the legend
patch = mpatches.Patch(color='#33AFFF', label='Actual')
patch2 = mpatches.Patch(color='#6ED06F', label='Planned')
plt.legend(handles=[patch, patch2], loc='upper left', fontsize = 'large')
plt.show()
Пример данных для zpp00141 (плановое расписание):
Operation short text,Operation/Activity,Earl. start / time,Latest finish / time,Work Center
Mount right racks,0250,7:00:00 AM,9:22:00 AM,503AL302
Mount right side motion unit carriage,0251,9:22:00 AM,10:30:00 AM,503AL302
Mount left side motion unit carriage,0252,10:30:00 AM,11:17:00 AM,503AL302
Install motion unit complete,0253,11:17:00 AM,1:01:00 PM,503AL302
Move machine to next step + EPA,0254,1:01:00 PM,3:30:00 PM,503AL302
Mount Left Racks,0200,7:00:00 AM,9:12:00 AM,503AL302
Mount cable motor & Lubricate guide carr,0201,9:12:00 AM,9:44:00 AM,503AL302
Mount suction components,0202,9:44:00 AM,11:04:00 AM,503AL302
Mount extraction,0203,11:04:00 AM,12:34:00 PM,503AL302
Mount temporary diamond plates,0204,12:34:00 PM,1:04:00 PM,503AL302
Mount piping inside,0205,1:04:00 PM,1:44:00 PM,503AL302
Move Machine to next step + EPA,0206,1:44:00 PM,3:30:00 PM,503AL302
Пример данных для zpp00138 (фактическое время) :
Work center,Operation/Activity,Operation short text,Actual finish (time),Actual start (time)
503AL302,0201,Mount cable motor & Lubricate guide carr,10:22:26 AM,9:32:41 AM
503AL302,0202,Mount suction components,2:21:41 PM,10:23:03 AM
503AL302,0203,Mount extraction,2:22:58 PM,2:22:26 PM
503AL302,0204,Mount temporary diamond plates,2:24:28 PM,2:24:00 PM
503AL302,0250,Mount right racks,9:34:26 AM,6:02:45 AM
503AL302,0251,Mount right side motion unit carriage,10:50:17 AM,9:35:47 AM
503AL302,0253,Install motion unit complete,2:02:47 PM,12:28:33 PM
503AL302,0254,Move machine to next step + EPA,2:14:35 PM,2:02:58 PM
503AL302,0200,Mount Left Racks,9:30:59 AM,7:02:30 AM
503AL302,0205,Mount piping inside,2:25:23 PM,2:24:51 PM
503AL302,0206,Move Machine to next step + EPA,4:12:31 PM,2:26:39 PM
503AL302,0252,Mount left side motion unit carriage,12:28:22 PM,10:51:01 AM