pythonplotlyplotly-python

How to specify color for elements in plotly Gannt chart?


I'm following the python tutorial here: https://plotly.com/python/gantt/

import pandas as pd
import plotly.express as px
df = pd.DataFrame([
    dict(Task="Job A", Start='2009-01-01', Finish='2009-02-25'),
    dict(Task="Job A", Start='2009-02-26', Finish='2009-03-28'),
    dict(Task="Job B", Start='2009-03-05', Finish='2009-04-15'),
    dict(Task="Job C", Start='2009-02-20', Finish='2009-05-30')
])

print(df)

    Task       Start      Finish
0  Job A  2009-01-01  2009-02-25
1  Job A  2009-02-26  2009-03-28
2  Job B  2009-03-05  2009-04-15
3  Job C  2009-02-20  2009-05-30

The code in the tutorial above gives me the chart:

fig = px.timeline(df, x_start="Start", x_end="Finish", y="Task")
fig.update_yaxes(autorange="reversed") # otherwise tasks are listed from the bottom up
fig.show()

enter image description here

Notice that there are two events for Job A.

I would like to alternate the colors for each start and finish. For example First event red, second event blue, third event red, fourth event blue etc.

I have tried the color_discrete_sequence and color_discrete_map arguments, but the colors do not alternate.

What I have tried:

fig = px.timeline(df, x_start="Start", x_end="Finish", y="Task",color_discrete_sequence=["red", "blue"])
fig.update_yaxes(autorange="reversed") 
fig.show()

and

fig = px.timeline(df, x_start="Start", x_end="Finish", y="Task",color_discrete_map={"Start": "red","Finish":'blue'})
fig.update_yaxes(autorange="reversed") 
fig.show()

Any ideas on how to alternate the colors?

AN example of what I want it to look like for Job A:

enter image description here


Solution

  • Just add a column that describes the desired color and map the description to the actual color. Without the mapping plotly will assign it's default colors.

    import pandas as pd
    import plotly.express as px
    
    df = pd.DataFrame([
        dict(Task="Job A", Start='2009-01-01', Finish='2009-02-25', Color='cyan'),
        dict(Task="Job A", Start='2009-02-26', Finish='2009-03-28', Color='red'),
        dict(Task="Job B", Start='2009-03-05', Finish='2009-04-15', Color='grey'),
        dict(Task="Job C", Start='2009-02-20', Finish='2009-05-30', Color='orange')
    ])
    cm = {x:x for x in df.Color.unique()}
    fig = px.timeline(df, x_start="Start", x_end="Finish", y="Task", color="Color", color_discrete_map=cm)
    fig.update_yaxes(autorange="reversed") # otherwise tasks are listed from the bottom up
    fig.show()