2016-09-09 2 views
6

Я пробовал несколько часов, чтобы выполнить эту работу. Я попробовал использовать пакет «python-gantt», без везения. Я также попытался замыслить (что было красиво, но я не могу размещать свои конфиденциальные данные на своем сайте, чтобы это не сработало).Создать диаграмму gantt с hlines?

Мой отправной точкой является код здесь: How to plot stacked event duration (Gantt Charts) using Python Pandas?

Три Требования:

  • Включить «Имя» на оси у, а не числа.
  • Если у кого-то есть несколько событий, поместите все периоды событий на одну строку (это упростит идентификацию шаблона), например. У Лизы будет только одна линия на визуальном.
  • Включите «Событие», указанное в верхней части соответствующей строки (если возможно), например. Первая линия Лизы сказала бы «Нанять».

код необходимо будет динамичным, чтобы разместить много больше людей и больше возможных типов событий ...

Я открыт для предложений, чтобы представить себе: Я хочу, чтобы показать длительность различных кадровых мероприятий в течение год, чтобы помочь выявить закономерности.

from datetime import datetime 
import pandas as pd 
import matplotlib.pyplot as plt 
import matplotlib.dates as dt 

df = pd.DataFrame({'Name': ['Joe','Joe','Lisa','Lisa','Lisa','Alice'], 
        'Event': ['Hire','Term','Hire','Transfer','Term','Term'], 
        'Start_Date': ["2014-01-01","2014-02-01","2015-01-01","2015-02-01","2015-03-01","2016-01-01"], 
        'End_Date': ["2014-01-31","2014-03-15","2015-01-31","2015-02-28","2015-05-01","2016-09-01"] 
        }) 

df = df[['Name','Event','Start_Date','End_Date']] 

df.Start_Date = pd.to_datetime(df.Start_Date).astype(datetime) 
df.End_Date = pd.to_datetime(df.End_Date).astype(datetime) 

fig = plt.figure() 
ax = fig.add_subplot(111) 
ax = ax.xaxis_date() 
ax = plt.hlines(df.index, dt.date2num(df.Start_Date), dt.date2num(df.End_Date)) 

ответ

6

Я столкнулся с той же проблемой в прошлом. Вы, кажется, цените эстетику Plotly. Вот небольшой фрагмент кода, который использует matplotlib.pyplot.broken_barh вместо matplotlib.pyplot.hlines.

Gantt Chart with broken_barh

from collections import defaultdict 
from datetime import datetime 
from datetime import date 
import pandas as pd 
import matplotlib.dates as mdates 
import matplotlib.patches as mpatches 
import matplotlib.pyplot as plt 

df = pd.DataFrame({ 
    'Name': ['Joe', 'Joe', 'Lisa', 'Lisa', 'Lisa', 'Alice'], 
    'Event': ['Hire', 'Term', 'Hire', 'Transfer', 'Term', 'Term'], 
    'Start_Date': ['2014-01-01', '2014-02-01', '2015-01-01', '2015-02-01', '2015-03-01', '2016-01-01'], 
    'End_Date': ['2014-01-31', '2014-03-15', '2015-01-31', '2015-02-28', '2015-05-01', '2016-09-01'] 
}) 

df = df[['Name', 'Event', 'Start_Date', 'End_Date']] 

df.Start_Date = pd.to_datetime(df.Start_Date).astype(datetime) 
df.End_Date = pd.to_datetime(df.End_Date).astype(datetime) 

names = df.Name.unique() 
nb_names = len(names) 

fig = plt.figure() 
ax = fig.add_subplot(111) 

bar_width = 0.8 
default_color = 'blue' 
colors_dict = defaultdict(lambda: default_color, Hire='green', Term='red', Transfer='orange') 

# Plot the events 
for index, name in enumerate(names): 
    mask = df.Name == name 
    start_dates = mdates.date2num(df.loc[mask].Start_Date) 
    end_dates = mdates.date2num(df.loc[mask].End_Date) 
    durations = end_dates - start_dates 
    xranges = zip(start_dates, durations) 
    ymin = index - bar_width/2.0 
    ywidth = bar_width 
    yrange = (ymin, ywidth) 
    facecolors = [colors_dict[event] for event in df.loc[mask].Event] 
    ax.broken_barh(xranges, yrange, facecolors=facecolors, alpha=1.0) 
    # you can set alpha to 0.6 to check if there are some overlaps 

# Shrink the x-axis 
box = ax.get_position() 
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height]) 

# Add the legend 
patches = [mpatches.Patch(color=color, label=key) for (key, color) in colors_dict.items()] 
patches = patches + [mpatches.Patch(color=default_color, label='Other')] 
plt.legend(handles=patches, bbox_to_anchor=(1, 0.5), loc='center left') 

# Format the x-ticks 
ax.xaxis.set_major_locator(mdates.YearLocator()) 
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y')) 
ax.xaxis.set_minor_locator(mdates.MonthLocator()) 

# Format the y-ticks 
ax.set_yticks(range(nb_names)) 
ax.set_yticklabels(names) 

# Set the limits 
date_min = date(df.Start_Date.min().year, 1, 1) 
date_max = date(df.End_Date.max().year + 1, 1, 1) 
ax.set_xlim(date_min, date_max) 

# Format the coords message box 
ax.format_xdata = mdates.DateFormatter('%Y-%m-%d') 

# Set the title 
ax.set_title('Gantt Chart') 

plt.show() 

Я надеюсь, что это поможет.

Смежные вопросы