Skip to content

Commit f032e5c

Browse files
feat(letsplot): implement gantt-basic (#2405)
## Implementation: `gantt-basic` - letsplot Implements the **letsplot** version of `gantt-basic`. **File:** `plots/gantt-basic/implementations/letsplot.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20543284331)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 72cb707 commit f032e5c

2 files changed

Lines changed: 168 additions & 0 deletions

File tree

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
""" pyplots.ai
2+
gantt-basic: Basic Gantt Chart
3+
Library: letsplot 4.8.2 | Python 3.13.11
4+
Quality: 91/100 | Created: 2025-12-27
5+
"""
6+
7+
import os
8+
from datetime import datetime
9+
10+
import pandas as pd
11+
from lets_plot import *
12+
13+
14+
LetsPlot.setup_html()
15+
16+
# Data - Software Development Project
17+
tasks_data = {
18+
"task": [
19+
"Requirements Gathering",
20+
"System Design",
21+
"UI/UX Design",
22+
"Backend Development",
23+
"Frontend Development",
24+
"Database Setup",
25+
"API Integration",
26+
"Unit Testing",
27+
"Integration Testing",
28+
"User Acceptance Testing",
29+
"Documentation",
30+
"Deployment",
31+
],
32+
"category": [
33+
"Planning",
34+
"Planning",
35+
"Design",
36+
"Development",
37+
"Development",
38+
"Development",
39+
"Development",
40+
"Testing",
41+
"Testing",
42+
"Testing",
43+
"Documentation",
44+
"Deployment",
45+
],
46+
"start": [
47+
datetime(2025, 1, 6),
48+
datetime(2025, 1, 13),
49+
datetime(2025, 1, 20),
50+
datetime(2025, 1, 27),
51+
datetime(2025, 2, 3),
52+
datetime(2025, 1, 27),
53+
datetime(2025, 2, 17),
54+
datetime(2025, 2, 10),
55+
datetime(2025, 2, 24),
56+
datetime(2025, 3, 3),
57+
datetime(2025, 2, 17),
58+
datetime(2025, 3, 10),
59+
],
60+
"end": [
61+
datetime(2025, 1, 10),
62+
datetime(2025, 1, 17),
63+
datetime(2025, 1, 31),
64+
datetime(2025, 2, 14),
65+
datetime(2025, 2, 21),
66+
datetime(2025, 2, 7),
67+
datetime(2025, 2, 28),
68+
datetime(2025, 2, 21),
69+
datetime(2025, 3, 7),
70+
datetime(2025, 3, 14),
71+
datetime(2025, 3, 7),
72+
datetime(2025, 3, 14),
73+
],
74+
}
75+
76+
df = pd.DataFrame(tasks_data)
77+
78+
# Convert dates to numeric for plotting (days since project start)
79+
project_start = datetime(2025, 1, 6)
80+
df["start_days"] = [(d - project_start).days for d in df["start"]]
81+
df["end_days"] = [(d - project_start).days for d in df["end"]]
82+
df["duration"] = df["end_days"] - df["start_days"]
83+
84+
# Order tasks by start date and assign y positions
85+
df = df.sort_values("start_days", ascending=False).reset_index(drop=True)
86+
df["y_pos"] = range(len(df))
87+
88+
# Create the Gantt chart using horizontal bars (geom_segment)
89+
plot = (
90+
ggplot(df, aes(x="start_days", y="y_pos", color="category"))
91+
+ geom_segment(aes(xend="end_days", yend="y_pos"), size=12, alpha=0.85)
92+
+ geom_point(size=4, shape=15) # Start markers
93+
+ geom_point(aes(x="end_days"), size=4, shape=15) # End markers
94+
+ scale_y_continuous(breaks=list(df["y_pos"]), labels=list(df["task"]), expand=[0.05, 0.05])
95+
+ scale_x_continuous(
96+
name="Project Timeline (Days from Start)",
97+
breaks=[0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70],
98+
labels=[
99+
"Week 1",
100+
"Week 2",
101+
"Week 3",
102+
"Week 4",
103+
"Week 5",
104+
"Week 6",
105+
"Week 7",
106+
"Week 8",
107+
"Week 9",
108+
"Week 10",
109+
"Week 11",
110+
],
111+
)
112+
+ scale_color_manual(values=["#306998", "#FFD43B", "#22C55E", "#EF4444", "#8B5CF6", "#06B6D4"], name="Phase")
113+
+ labs(title="gantt-basic · letsplot · pyplots.ai", x="Project Timeline", y="Tasks")
114+
+ theme_minimal()
115+
+ theme(
116+
plot_title=element_text(size=28, face="bold"),
117+
axis_title_x=element_text(size=22),
118+
axis_title_y=element_text(size=22),
119+
axis_text_x=element_text(size=16, angle=45),
120+
axis_text_y=element_text(size=16),
121+
legend_title=element_text(size=18),
122+
legend_text=element_text(size=16),
123+
legend_position="right",
124+
panel_grid_major_x=element_line(color="#E5E5E5", size=0.5),
125+
panel_grid_major_y=element_line(color="#F5F5F5", size=0.3),
126+
panel_grid_minor=element_blank(),
127+
)
128+
+ ggsize(1600, 900)
129+
)
130+
131+
# Save as PNG (scale 3x for 4800 × 2700 px)
132+
ggsave(plot, "plot.png", scale=3, path=".")
133+
134+
# Save interactive HTML version
135+
ggsave(plot, "plot.html", path=".")
136+
137+
# Clean up lets-plot-images folder if created
138+
if os.path.exists("lets-plot-images"):
139+
import shutil
140+
141+
shutil.rmtree("lets-plot-images")
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
library: letsplot
2+
specification_id: gantt-basic
3+
created: '2025-12-27T19:22:28Z'
4+
updated: '2025-12-27T19:25:45Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20543284331
7+
issue: 0
8+
python_version: 3.13.11
9+
library_version: 4.8.2
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/gantt-basic/letsplot/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/gantt-basic/letsplot/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/gantt-basic/letsplot/plot.html
13+
quality_score: 91
14+
review:
15+
strengths:
16+
- Excellent visual clarity with proper bar sizing and spacing between tasks
17+
- Smart use of geom_segment with square end markers for clean Gantt bar appearance
18+
- Professional color palette with 6 distinct phase colors
19+
- Well-structured realistic software development project data
20+
- Proper canvas sizing (1600x900 with scale=3) for 4800x2700 output
21+
- Clean week-based x-axis labeling making timeline easy to follow
22+
- Tasks logically sorted by start date for natural reading flow
23+
weaknesses:
24+
- Missing today marker (vertical reference line) which spec notes suggest
25+
- Blue and teal colors for Planning and Deployment phases could be more distinct
26+
for colorblind accessibility
27+
- Cleanup code for lets-plot-images folder adds unnecessary complexity

0 commit comments

Comments
 (0)