import numpy as np
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime, timedelta
task_count = 3
total_duration = 12
tasks = np.random.dirichlet(np.ones(task_count), size=12)
task_names = [f"Task {chr(97 + n).title()}" for n in range(task_count)]
task_times = []
s = datetime.combine(datetime.today(), datetime.min.time())
for task in tasks:
for x in range(len(task)):
t, n = task[x], task_names[x]
e = s + timedelta(hours=t)
task_times.append((n, s, e, t))
s = e
df = pd.DataFrame(task_times, columns=['Task', 'Start', 'End', 'Duration'])
df.sample(5)
Task | Start | End | Duration | |
---|---|---|---|---|
26 | Task C | 2021-11-13 08:48:05.393000 | 2021-11-13 09:00:00.000000 | 0.198502 |
3 | Task A | 2021-11-13 01:00:00.000000 | 2021-11-13 01:20:27.438916 | 0.340955 |
16 | Task B | 2021-11-13 05:38:15.042744 | 2021-11-13 05:52:25.096626 | 0.236126 |
4 | Task B | 2021-11-13 01:20:27.438916 | 2021-11-13 01:31:57.862418 | 0.191784 |
10 | Task B | 2021-11-13 03:00:27.627826 | 2021-11-13 03:01:35.381166 | 0.018820 |
# ezpz way
fig = px.timeline(df, x_start='Start', x_end='End', y='Task', color='Task')
date = s.strftime("%d-%b-%Y")
for x in fig.data:
x.y = [date for _ in x.y]
fig.update_layout(
title='Task Durations',
yaxis={'title': 'Date'}
)
fig.show()
# Harder but more customizable way
data = []
date = s.strftime("%d-%b-%Y")
for task, rows in df.groupby('Task'):
bar = go.Bar(
x=(rows['End'] - rows['Start']).astype('timedelta64[ms]'),
y=[date for _ in range(len(rows))],
base=rows['Start'], name=task,
legendgroup=task, offsetgroup=task,
orientation='h', showlegend=True,
)
data.append(bar)
fig = go.Figure(data=data)
fig.update_layout(
title='Task Durations', barmode='overlay',
yaxis={'title': 'Date'},
xaxis={'anchor': 'y', 'type': 'date'}
)
fig.show()