2016-09-09 5 views
6

Ich habe mehrere Stunden versucht, diese Arbeit zu machen. Ich habe versucht, Python-Gantt-Paket zu verwenden, ohne Glück. Ich habe auch versucht, plotly (das war schön, aber ich kann nicht meine sensiblen Daten auf ihrer Website hosten, so dass es nicht funktioniert).Gantt-Diagramm mit Linien erstellen?

Mein Ausgangspunkt ist der Code von hier: How to plot stacked event duration (Gantt Charts) using Python Pandas?

Drei Anforderungen:

  • Fügen Sie den 'Namen' auf der y-Achse, anstatt die Zahlen.
  • Wenn mehrere Ereignisse vorhanden sind, legen Sie alle Ereigniszeiträume auf eine Zeile (dies erleichtert die Mustererkennung), z. Lisa wird nur eine Zeile auf dem Bild haben.
  • Fügen Sie das "Ereignis" oben auf der entsprechenden Zeile (wenn möglich) ein, z. Lisas erste Zeile würde "Hire" sagen.

Der Code muss dynamisch sein viel mehr Menschen aufnehmen und mehr möglich Ereignistypen ...

Ich bin offen für Vorschläge zu visualisieren: Ich habe die Dauer für verschiedene Personal Veranstaltungen während zeigen wollen das Jahr, um Muster zu identifizieren.

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

Antwort

6

Ich stieß auf das gleiche Problem in der Vergangenheit. Sie scheinen die Ästhetik von Plotly zu schätzen. Hier ist ein kleines Stück Code, der matplotlib.pyplot.broken_barh statt matplotlib.pyplot.hlines verwendet.

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

Ich hoffe, dies wird Ihnen helfen.

Verwandte Themen