Gantt chart
fabricated software project with multicategory team/task axes
Example from the compendium of canonical charts
Python Code
"""Gantt chart — fabricated software project with multicategory team/task axes."""
import pandas as pd
import numpy as np
import plotly.graph_objects as go
# Fabricated 10-week sprint plan
# [team, task_name, start_day, end_day, color_key]
TASKS = [
# Team Alpha
("Team Alpha", "Task 1 · Requirements", 0, 7, VIOLET),
("Team Alpha", "Task 2 · Architecture", 5, 14, VIOLET),
("Team Alpha", "Task 3 · Backend Build", 12, 35, VIOLET),
("Team Alpha", "Task 4 · Integration", 30, 42, VIOLET),
# Team Beta
("Team Beta", "Task 5 · UI Design", 3, 18, GREEN),
("Team Beta", "Task 6 · Frontend Build", 15, 35, GREEN),
("Team Beta", "Task 7 · QA Testing", 32, 45, GREEN),
# Team Gamma
("Team Gamma", "Task 8 · Infra Setup", 0, 10, TEAL),
("Team Gamma", "Task 9 · CI/CD Pipeline", 8, 20, TEAL),
("Team Gamma", "Task 10 · Deploy & Monitor",40, 50, TEAL),
]
START_DATE = pd.Timestamp("2025-01-06") # Monday
def generate():
print("building fabricated multicategory Gantt chart …")
rows = []
for team, task, d0, d1, color in TASKS:
rows.append({
"team": team,
"task": task,
"start": START_DATE + pd.Timedelta(days=d0),
"end": START_DATE + pd.Timedelta(days=d1),
"color": color,
})
df = pd.DataFrame(rows)
# Multicategory y-axis: [team, task] pairs (task 1 at top → reversed order)
y_labels = [[row["team"], row["task"]] for _, row in df.iterrows()]
fig = go.Figure()
# One trace per team for legend grouping
teams = ["Team Alpha", "Team Beta", "Team Gamma"]
team_colors = [VIOLET, GREEN, TEAL]
for team, color in zip(teams, team_colors):
sub = df[df["team"] == team]
for _, row in sub.iterrows():
duration_ms = (row["end"] - row["start"]).total_seconds() * 1000
fig.add_trace(go.Bar(
x=[duration_ms],
y=[[row["team"], row["task"]]],
base=[row["start"].value // 10**6], # ms timestamp
orientation="h",
marker=dict(color=color, opacity=0.85,
line=dict(color="white", width=1.5)),
name=team,
legendgroup=team,
showlegend=bool(row.name == sub.index[0]), # show once per team
hovertemplate=(
f"<b>{row['task']}</b><br>"
f"{row['start'].strftime('%b %d')} – {row['end'].strftime('%b %d')}<br>"
f"{(row['end'] - row['start']).days} days<extra></extra>"
),
))
# Milestone marker: launch day
launch = START_DATE + pd.Timedelta(days=50)
fig.add_vline(
x=launch.value // 10**6,
line=dict(color=PINK, width=2, dash="dash"),
annotation_text="Launch",
annotation_position="top",
annotation_font=dict(size=11, color=PINK),
)
fig.update_layout(
barmode="overlay",
xaxis=dict(
title="",
type="date",
showgrid=True,
dtick="M1",
tickformat="%b %d",
),
yaxis=dict(
autorange="reversed",
type="multicategory",
showgrid=True,
gridcolor="#e8e8f0",
),
legend=dict(orientation="h", y=1.08),
bargap=0.25,
margin=dict(t=50, b=50, l=20, r=40),
height=480,
)
return fig
if __name__ == "__main__":
generate()
Made with Plotly