def ageing_wip_chart(cycle_data, start_column, end_column, done_column=None, now=None, title=None, ax=None):
if len(cycle_data.index) == 0:
raise UnchartableData("Cannot draw ageing WIP chart with no data")
if ax is None:
fig, ax = plt.subplots()
if title is not None:
ax.set_title(title)
if now is None:
now = pd.Timestamp.now()
if done_column is None:
done_column = cycle_data.columns[-1]
today = now.date()
# remove items that are done
cycle_data = cycle_data[pd.isnull(cycle_data[done_column])]
# Check that we still have some data to proceed with.
if len(cycle_data.index) == 0:
raise UnchartableData("Cannot draw ageing WIP chart with no data - All items done!")
cycle_data = pd.concat((
cycle_data[['key', 'summary']],
cycle_data.ix[:, start_column:end_column]
), axis=1)
def extract_status(row):
last_valid = row.last_valid_index()
if last_valid is None:
return np.NaN
return last_valid
def extract_age(row):
started = row[start_column]
if pd.isnull(started):
return np.NaN
return (today - started.date()).days
wip_data = cycle_data[['key', 'summary']].copy()
wip_data['status'] = cycle_data.apply(extract_status, axis=1)
wip_data['age'] = cycle_data.apply(extract_age, axis=1)
wip_data.dropna(how='any', inplace=True)
sns.swarmplot(x='status', y='age', order=cycle_data.columns[2:], data=wip_data, ax=ax)
ax.set_xlabel("Status")
ax.set_ylabel("Age (days)")
ax.set_xticklabels(ax.xaxis.get_majorticklabels(), rotation=90)
bottom, top = ax.get_ylim()
ax.set_ylim(0, top)
return ax
评论列表
文章目录