|
| 1 | +""" pyplots.ai |
| 2 | +gantt-basic: Basic Gantt Chart |
| 3 | +Library: matplotlib 3.10.8 | Python 3.13.11 |
| 4 | +Quality: 95/100 | Created: 2025-12-27 |
| 5 | +""" |
| 6 | + |
| 7 | +from datetime import datetime, timedelta |
| 8 | + |
| 9 | +import matplotlib.dates as mdates |
| 10 | +import matplotlib.pyplot as plt |
| 11 | +from matplotlib.patches import Patch |
| 12 | + |
| 13 | + |
| 14 | +# Data - Software Development Project |
| 15 | +tasks = [ |
| 16 | + { |
| 17 | + "task": "Requirements Analysis", |
| 18 | + "start": datetime(2025, 1, 6), |
| 19 | + "end": datetime(2025, 1, 17), |
| 20 | + "category": "Planning", |
| 21 | + }, |
| 22 | + {"task": "System Design", "start": datetime(2025, 1, 13), "end": datetime(2025, 1, 31), "category": "Planning"}, |
| 23 | + {"task": "Database Setup", "start": datetime(2025, 1, 27), "end": datetime(2025, 2, 7), "category": "Development"}, |
| 24 | + { |
| 25 | + "task": "Backend Development", |
| 26 | + "start": datetime(2025, 2, 3), |
| 27 | + "end": datetime(2025, 3, 7), |
| 28 | + "category": "Development", |
| 29 | + }, |
| 30 | + { |
| 31 | + "task": "Frontend Development", |
| 32 | + "start": datetime(2025, 2, 10), |
| 33 | + "end": datetime(2025, 3, 14), |
| 34 | + "category": "Development", |
| 35 | + }, |
| 36 | + {"task": "API Integration", "start": datetime(2025, 3, 3), "end": datetime(2025, 3, 21), "category": "Development"}, |
| 37 | + {"task": "Unit Testing", "start": datetime(2025, 3, 10), "end": datetime(2025, 3, 28), "category": "Testing"}, |
| 38 | + { |
| 39 | + "task": "Integration Testing", |
| 40 | + "start": datetime(2025, 3, 24), |
| 41 | + "end": datetime(2025, 4, 11), |
| 42 | + "category": "Testing", |
| 43 | + }, |
| 44 | + { |
| 45 | + "task": "User Acceptance Testing", |
| 46 | + "start": datetime(2025, 4, 7), |
| 47 | + "end": datetime(2025, 4, 18), |
| 48 | + "category": "Testing", |
| 49 | + }, |
| 50 | + {"task": "Documentation", "start": datetime(2025, 3, 17), "end": datetime(2025, 4, 11), "category": "Deployment"}, |
| 51 | + {"task": "Deployment Prep", "start": datetime(2025, 4, 14), "end": datetime(2025, 4, 25), "category": "Deployment"}, |
| 52 | + {"task": "Go Live", "start": datetime(2025, 4, 28), "end": datetime(2025, 5, 2), "category": "Deployment"}, |
| 53 | +] |
| 54 | + |
| 55 | +# Category colors (Python Blue variations + complementary) |
| 56 | +category_colors = { |
| 57 | + "Planning": "#306998", # Python Blue |
| 58 | + "Development": "#FFD43B", # Python Yellow |
| 59 | + "Testing": "#4B8BBE", # Light Python Blue |
| 60 | + "Deployment": "#646464", # Neutral Gray |
| 61 | +} |
| 62 | + |
| 63 | +# Create plot |
| 64 | +fig, ax = plt.subplots(figsize=(16, 9)) |
| 65 | + |
| 66 | +# Sort tasks by start date for logical ordering |
| 67 | +tasks_sorted = sorted(tasks, key=lambda x: x["start"], reverse=True) |
| 68 | + |
| 69 | +# Draw bars |
| 70 | +bar_height = 0.6 |
| 71 | +y_positions = range(len(tasks_sorted)) |
| 72 | + |
| 73 | +for i, task in enumerate(tasks_sorted): |
| 74 | + start = task["start"] |
| 75 | + duration = (task["end"] - task["start"]).days |
| 76 | + color = category_colors[task["category"]] |
| 77 | + |
| 78 | + ax.barh(i, duration, left=start, height=bar_height, color=color, edgecolor="white", linewidth=1.5, alpha=0.9) |
| 79 | + |
| 80 | +# Y-axis: task names |
| 81 | +ax.set_yticks(y_positions) |
| 82 | +ax.set_yticklabels([t["task"] for t in tasks_sorted], fontsize=16) |
| 83 | + |
| 84 | +# X-axis: dates |
| 85 | +ax.xaxis.set_major_locator(mdates.WeekdayLocator(byweekday=mdates.MO, interval=2)) |
| 86 | +ax.xaxis.set_major_formatter(mdates.DateFormatter("%b %d")) |
| 87 | +ax.tick_params(axis="x", labelsize=14, rotation=45) |
| 88 | + |
| 89 | +# Set x-axis limits with padding |
| 90 | +all_starts = [t["start"] for t in tasks] |
| 91 | +all_ends = [t["end"] for t in tasks] |
| 92 | +ax.set_xlim(min(all_starts) - timedelta(days=3), max(all_ends) + timedelta(days=3)) |
| 93 | + |
| 94 | +# Add "today" marker line (mid-project for demonstration) |
| 95 | +today = datetime(2025, 3, 15) |
| 96 | +ax.axvline(today, color="#E74C3C", linewidth=2.5, linestyle="--", label="Today (Mar 15)", zorder=5) |
| 97 | + |
| 98 | +# Labels and title |
| 99 | +ax.set_xlabel("Timeline", fontsize=20) |
| 100 | +ax.set_ylabel("Tasks", fontsize=20) |
| 101 | +ax.set_title("gantt-basic · matplotlib · pyplots.ai", fontsize=24, fontweight="bold") |
| 102 | + |
| 103 | +# Grid (subtle, only on x-axis) |
| 104 | +ax.grid(True, axis="x", alpha=0.3, linestyle="--") |
| 105 | +ax.set_axisbelow(True) |
| 106 | + |
| 107 | +# Legend for categories |
| 108 | +legend_elements = [Patch(facecolor=color, edgecolor="white", label=cat) for cat, color in category_colors.items()] |
| 109 | +legend_elements.append(plt.Line2D([0], [0], color="#E74C3C", linewidth=2.5, linestyle="--", label="Today")) |
| 110 | +ax.legend(handles=legend_elements, loc="upper right", fontsize=14, framealpha=0.95) |
| 111 | + |
| 112 | +# Remove top and right spines for cleaner look |
| 113 | +ax.spines["top"].set_visible(False) |
| 114 | +ax.spines["right"].set_visible(False) |
| 115 | + |
| 116 | +plt.tight_layout() |
| 117 | +plt.savefig("plot.png", dpi=300, bbox_inches="tight") |
0 commit comments