0

Is there a way to separate tasks on a Gantt diagram if they have the same names?

import plotly.express as px
import pandas as pd

df = pd.DataFrame([
    dict(Task="Job A", Start='2009-01-01', Finish='2009-02-28', Worker='Alex'),
    dict(Task="Job B", Start='2009-03-05', Finish='2009-04-15', Worker='John'),
    dict(Task="Job A", Start='2009-02-20', Finish='2009-05-30', Worker='Marc')
])

fig = px.timeline(df, x_start="Start", x_end="Finish", y="Task", color="Worker")
fig.update_yaxes(autorange="reversed") 
fig.show()

I want to show two jobs named "Job A" as separate tasks, not grouping and not in one line using opacity, and preferably not using deprecated plotly.figure_factory.create_gantt. Thanks in advance!

2
  • Maybe if every task had unique ID then you could use it as y and it would put it in separate line. It would need only to change labels on Y-axis to Tasks. You could also try y=df.index
    – furas
    Commented Jun 26 at 12:51
  • it seems there is (deprecated) create_gantt() which could use option group_tasks=False, See: Gantt
    – furas
    Commented Jun 26 at 13:03

2 Answers 2

2

You could do something like this :

df = pd.DataFrame([
    dict(Task="Job A", Start='2009-01-01', Finish='2009-02-28', Worker='Alex'),
    dict(Task="Job B", Start='2009-03-05', Finish='2009-04-15', Worker='John'),
    dict(Task="Job A", Start='2009-02-20', Finish='2009-05-30', Worker='Marc')
])

# Add a column to help identify unique task per worker
df['id'] = df['Task'] + ':' + df['Worker']
df = df.sort_values('id').reset_index()

# Use that column instead
fig = px.timeline(df, x_start="Start", x_end="Finish", y='id', color="Worker")

# Optionally, if you want to preserve original yaxis title and tick labels
fig.update_yaxes(title='Task', tickmode='array', tickvals=df['id'], ticktext=df['Task'])

fig.update_yaxes(autorange="reversed")
fig.show()
1

It seems there is deprecated function create_gantt() which has option group_tasks=False

import plotly.express as px
import pandas as pd

df = pd.DataFrame([
    dict(Task="Job A", Start='2009-01-01', Finish='2009-02-28', Worker='Alex'),
    dict(Task="Job B", Start='2009-03-05', Finish='2009-04-15', Worker='John'),
    dict(Task="Job A", Start='2009-02-20', Finish='2009-05-30', Worker='Marc')
])

import plotly.figure_factory as ff
fig = ff.create_gantt(df, index_col='Task', group_tasks=False)
fig.update_yaxes(autorange="reversed")
fig.show()

But it is deprecated so some day it may not work.
And it looks little different. It may need other functions to add text and legend.

enter image description here


You may have to use unique value in y= - for example df.index (it doesn't have to be converted to string) - and it will put every value in separate row.

Later you have to only use update_yaxes() to replace text (using text=) and labels on y-axis (using ticktext= with tickvals=).

import plotly.express as px
import pandas as pd

df = pd.DataFrame([
    dict(Task="Job A", Start='2009-01-01', Finish='2009-02-28', Worker='Alex'),
    dict(Task="Job B", Start='2009-03-05', Finish='2009-04-15', Worker='John'),
    dict(Task="Job A", Start='2009-02-20', Finish='2009-05-30', Worker='Marc')
])

fig = px.timeline(df, x_start="Start", x_end="Finish", y=df.index, color="Worker")
fig.update_yaxes(autorange="reversed", title='Task', ticktext=df['Task'], tickvals=df.index) 

fig.show()

enter image description here

2
  • funny, it seems you didn't see my answer (it's a bit redundant). Commented Jun 26 at 14:33
  • I was working long time for this answer (for example I was checking source code for create_gantt) and I didn't refresh this page - so I saw your answer after adding my answer :)
    – furas
    Commented Jun 26 at 14:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.