GANTT
Excel Usage
=GANTT(data, title, xlabel, ylabel, color_map, legend)
data(list[list], required): Input data (Labels, Start, Duration).title(str, optional, default: null): Chart title.xlabel(str, optional, default: null): Label for X-axis.ylabel(str, optional, default: null): Label for Y-axis.color_map(str, optional, default: “viridis”): Color map for tasks.legend(str, optional, default: “false”): Show legend.
Returns (object): Matplotlib Figure object (standard Python) or base64 encoded PNG string (Pyodide).
Examples
Example 1: Project timeline with multiple tasks
Inputs:
| data | ||
|---|---|---|
| Design | 0 | 5 |
| Development | 4 | 10 |
| Testing | 12 | 4 |
| Deployment | 15 | 2 |
Excel formula:
=GANTT({"Design",0,5;"Development",4,10;"Testing",12,4;"Deployment",15,2})
Expected output:
"chart"
Example 2: Gantt with custom axis labels and title
Inputs:
| data | title | xlabel | ylabel | ||
|---|---|---|---|---|---|
| Phase 1 | 0 | 3 | Project Schedule | Days | Tasks |
| Phase 2 | 2 | 4 |
Excel formula:
=GANTT({"Phase 1",0,3;"Phase 2",2,4}, "Project Schedule", "Days", "Tasks")
Expected output:
"chart"
Example 3: Gantt with legend
Inputs:
| data | legend | ||
|---|---|---|---|
| Task A | 0 | 5 | true |
| Task B | 3 | 6 |
Excel formula:
=GANTT({"Task A",0,5;"Task B",3,6}, "true")
Expected output:
"chart"
Example 4: Custom color map
Inputs:
| data | color_map | ||
|---|---|---|---|
| Sprint 1 | 0 | 14 | plasma |
| Sprint 2 | 14 | 14 | |
| Sprint 3 | 28 | 14 |
Excel formula:
=GANTT({"Sprint 1",0,14;"Sprint 2",14,14;"Sprint 3",28,14}, "plasma")
Expected output:
"chart"
Python Code
import sys
import matplotlib
IS_PYODIDE = sys.platform == "emscripten"
if IS_PYODIDE:
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import io
import base64
import numpy as np
def gantt(data, title=None, xlabel=None, ylabel=None, color_map='viridis', legend='false'):
"""
Create a Gantt chart (timeline of tasks).
See: https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.broken_barh.html
This example function is provided as-is without any representation of accuracy.
Args:
data (list[list]): Input data (Labels, Start, Duration).
title (str, optional): Chart title. Default is None.
xlabel (str, optional): Label for X-axis. Default is None.
ylabel (str, optional): Label for Y-axis. Default is None.
color_map (str, optional): Color map for tasks. Valid options: Viridis, Plasma, Inferno, Magma, Cividis. Default is 'viridis'.
legend (str, optional): Show legend. Valid options: True, False. Default is 'false'.
Returns:
object: Matplotlib Figure object (standard Python) or base64 encoded PNG string (Pyodide).
"""
def to2d(x):
return [[x]] if not isinstance(x, list) else x
try:
data = to2d(data)
if not isinstance(data, list) or len(data) == 0:
return "Error: Data must be a non-empty 2D list"
# Extract labels, starts, and durations
labels = []
starts = []
durations = []
for row in data:
if not isinstance(row, list) or len(row) < 3:
continue
try:
label = str(row[0]) if row[0] else "Task"
start = float(row[1])
duration = float(row[2])
if duration <= 0:
continue
labels.append(label)
starts.append(start)
durations.append(duration)
except (TypeError, ValueError):
continue
if len(labels) == 0:
return "Error: No valid task data found"
# Create the figure
fig, ax = plt.subplots(figsize=(10, max(4, len(labels) * 0.6)))
# Get colormap
try:
cmap = plt.get_cmap(color_map)
colors = [cmap(i / len(labels)) for i in range(len(labels))]
except:
colors = ['steelblue'] * len(labels)
# Create Gantt chart using horizontal bars
y_pos = np.arange(len(labels))
for i, (start, duration, color, label) in enumerate(zip(starts, durations, colors, labels)):
ax.barh(i, duration, left=start, height=0.6, color=color,
edgecolor='black', linewidth=0.5, label=label if legend == "true" else None)
ax.set_yticks(y_pos)
ax.set_yticklabels(labels)
ax.invert_yaxis()
if xlabel:
ax.set_xlabel(str(xlabel))
else:
ax.set_xlabel('Time')
if ylabel:
ax.set_ylabel(str(ylabel))
if title:
ax.set_title(str(title))
if legend == "true":
ax.legend(loc='best', fontsize='small')
ax.grid(True, axis='x', alpha=0.3)
plt.tight_layout()
if IS_PYODIDE:
buf = io.BytesIO()
plt.savefig(buf, format='png', dpi=100, bbox_inches='tight')
buf.seek(0)
img_base64 = base64.b64encode(buf.read()).decode('utf-8')
plt.close(fig)
return f"data:image/png;base64,{img_base64}"
else:
return fig
except Exception as e:
return f"Error: {str(e)}"