HOWTO · Plotly
How to Plot Gantt Chart in Plotly
This article teaches you to create a Gantt chart using the timeline() and create_gantt() function of Plotly in Python.
On this page
Gantt charts display a project schedule as horizontal bars: each bar covers the start and finish dates of one task. This tutorial creates a Gantt chart in Python with Plotly using the timeline() function of plotly.express and the create_gantt() function of plotly.figure_factory, then adjusts the chart’s colors, labels, and layout.
Create a Gantt chart with plotly.express.timeline()
The timeline() function builds a Gantt chart from records that supply three fields: Task, the job name as a string; Start, the start date; and Finish, the end date. Pass those field names to the x_start, x_end, and y arguments. Plotly parses date strings in year-month-day form on its own.
The example below defines three jobs as a list of dictionaries and gives each bar its own color by mapping color to Task. fig.write_html() saves the figure as a standalone page that opens in any browser; in a notebook or interactive session, call fig.show() instead to render the figure inline.
import plotly.express as px
df = [
dict(Task="Job A", Start="2022-01-01", Finish="2022-02-28"),
dict(Task="Job B", Start="2022-03-05", Finish="2022-04-15"),
dict(Task="Job C", Start="2022-02-20", Finish="2022-05-30"),
]
fig = px.timeline(df, x_start="Start", x_end="Finish", y="Task", color="Task")
fig.write_html("gantt-timeline.html")
The saved page renders this chart:
Customize a plotly.express Gantt chart
Swap the default palette for a qualitative sequence such as Light24 or Dark24 with the color_discrete_sequence argument.
import plotly.express as px
df = [
dict(Task="Job A", Start="2022-01-01", Finish="2022-02-28"),
dict(Task="Job B", Start="2022-03-05", Finish="2022-04-15"),
dict(Task="Job C", Start="2022-02-20", Finish="2022-05-30"),
]
fig = px.timeline(
df,
x_start="Start",
x_end="Finish",
y="Task",
color="Task",
color_discrete_sequence=px.colors.qualitative.Light24,
)
fig.write_html("gantt-light24.html")
The saved page renders this chart:
To pin an exact color to a named task, pass a dictionary to color_discrete_map; tasks left out of the dictionary keep colors from the active sequence.
import plotly.express as px
df = [
dict(Task="Job A", Start="2022-01-01", Finish="2022-02-28"),
dict(Task="Job B", Start="2022-03-05", Finish="2022-04-15"),
dict(Task="Job C", Start="2022-02-20", Finish="2022-05-30"),
]
fig = px.timeline(
df,
x_start="Start",
x_end="Finish",
y="Task",
color="Task",
color_discrete_map={"Job A": "yellow", "Job B": "black"},
)
fig.write_html("gantt-color-map.html")
The saved page renders this chart:
The title argument sets the chart heading, and width and height set the figure size in pixels. hover_name chooses the label shown when hovering over a bar, text prints a label inside each bar, and opacity takes a value from 0 to 1. facet_row or facet_col split the chart into one subplot per value, and facet_row_spacing and facet_col_spacing control the gap between subplots as a fraction from 0 to 1.
import plotly.express as px
df = [
dict(Task="Job A", Start="2022-01-01", Finish="2022-02-28"),
dict(Task="Job B", Start="2022-03-05", Finish="2022-04-15"),
dict(Task="Job C", Start="2022-02-20", Finish="2022-05-30"),
]
fig = px.timeline(
df,
x_start="Start",
x_end="Finish",
y="Task",
color="Task",
title="Gantt Chart",
hover_name="Task",
text="Task",
opacity=0.8,
facet_row="Task",
)
fig.write_html("gantt-facets.html")
The saved page renders this chart:
Create and customize a Gantt chart with plotly.figure_factory.create_gantt()
The create_gantt() function builds the same kind of chart from the same three fields. It accepts a list of dictionaries, the form used below, or a pandas DataFrame with Task, Start, and Finish columns. Plotly marks create_gantt() as deprecated in favor of timeline(), and Plotly 7 removed the function entirely, so the call only works on Plotly 6 or earlier. Each script below checks hasattr() first; on a release without the function it prints a notice instead of drawing the chart.
import plotly.figure_factory as pff
df = [
dict(Task="Job A", Start="2022-01-01", Finish="2022-02-28"),
dict(Task="Job B", Start="2022-03-05", Finish="2022-04-15"),
dict(Task="Job C", Start="2022-02-20", Finish="2022-05-30"),
]
if hasattr(pff, "create_gantt"):
fig = pff.create_gantt(df)
fig.show()
else:
print("create_gantt() is not available in this Plotly release")
On Plotly 7 the script prints:
create_gantt() is not available in this Plotly release
On Plotly 6 or earlier it renders this chart:
Give index_col the field whose values drive bar color, then assign each index value an rgb() or hex color through a colors dictionary.
import plotly.figure_factory as pff
df = [
dict(Task="Job A", Start="2022-01-01", Finish="2022-02-28"),
dict(Task="Job B", Start="2022-03-05", Finish="2022-04-15"),
dict(Task="Job C", Start="2022-02-20", Finish="2022-05-30"),
]
if hasattr(pff, "create_gantt"):
fig = pff.create_gantt(
df,
index_col="Task",
colors={"Job A": "rgb(255,0,0)", "Job B": "rgb(0,255,0)", "Job C": "rgb(0,0,255)"},
)
fig.show()
else:
print("create_gantt() is not available in this Plotly release")
On Plotly 7 the script prints:
create_gantt() is not available in this Plotly release
On Plotly 6 or earlier it renders this chart:
The remaining options mirror the plotly.express arguments: title, width, and height set the heading and figure size, bar_width sets bar thickness, and showgrid_x and showgrid_y toggle the axis grids. show_hover_fill enables or disables hover text on the bar fill, and group_tasks set to True draws tasks that share an index_col value on a single row. show_colorbar displays a color scale, but only when the index column holds numbers; a text index such as Task produces a legend instead.
import plotly.figure_factory as pff
df = [
dict(Task="Job A", Start="2022-01-01", Finish="2022-02-28"),
dict(Task="Job B", Start="2022-03-05", Finish="2022-04-15"),
dict(Task="Job C", Start="2022-02-20", Finish="2022-05-30"),
]
if hasattr(pff, "create_gantt"):
fig = pff.create_gantt(
df,
index_col="Task",
colors={"Job A": "rgb(255,0,0)", "Job B": "rgb(0,255,0)", "Job C": "rgb(0,0,255)"},
show_colorbar=True,
group_tasks=True,
showgrid_x=True,
bar_width=0.5,
)
fig.show()
else:
print("create_gantt() is not available in this Plotly release")
On Plotly 7 the script prints:
create_gantt() is not available in this Plotly release
On Plotly 6 or earlier it renders this chart:
Choose an API and validate the chart
For new code, prefer timeline(): it is part of plotly.express, runs on current Plotly releases, and covers the same task data. Keep create_gantt() in mind when maintaining code written for Plotly 6 or earlier; its figures also add a date range-selector row above the plot, as the images above show.
The timeline() figure keeps one trace per value in the color column, so printing the trace names confirms which tasks made it into the chart. Run this example:
import plotly.express as px
df = [
dict(Task="Job A", Start="2022-01-01", Finish="2022-02-28"),
dict(Task="Job B", Start="2022-03-05", Finish="2022-04-15"),
dict(Task="Job C", Start="2022-02-20", Finish="2022-05-30"),
]
fig = px.timeline(df, x_start="Start", x_end="Finish", y="Task", color="Task")
print([trace.name for trace in fig.data])
['Job A', 'Job B', 'Job C']
Each printed name matches a task from the data, so the chart holds one bar per job.