0

I am trying to visualize different phases in a series of videos using plotly express timeline. I want to create one bar per video and color the phases of each video differently. That means same phase, same color.

Here are some lines of the dataframe:

                            Task   Start  Finish Resource  delta
vid_idx                                                         
Video_002_007_1  Video_002_007_1       0      91        0     91
Video_002_007_1  Video_002_007_1      92     371        1    279
Video_002_007_1  Video_002_007_1     372     630       12    258
Video_002_007_1  Video_002_007_1     631   12352        1  11721
Video_002_007_1  Video_002_007_1   12353   60336        2  47983
Video_002_007_1  Video_002_007_1   60337   67641       3a   7304
Video_002_007_1  Video_002_007_1   67642   69134        2   1492
Video_002_007_1  Video_002_007_1   69135   69396       3b    261
Video_002_007_1  Video_002_007_1   69397   73963       3a   4566
Video_002_007_1  Video_002_007_1   73964   76800       3b   2836
Video_002_007_1  Video_002_007_1   76801   95566        4  18765
Video_002_007_1  Video_002_007_1   95567   97920        5   2353
Video_002_007_1  Video_002_007_1   97921   98119       12    198
Video_002_007_1  Video_002_007_1   98120   99171        5   1051
Video_002_007_1  Video_002_007_1   99172   99260       12     88
Video_002_007_1  Video_002_007_1   99261  102295        5   3034
Video_002_007_1  Video_002_007_1  102296  102378       12     82
Video_002_007_1  Video_002_007_1  102379  103045        5    666
Video_002_007_1  Video_002_007_1  103046  111433        6   8387
Video_002_007_1  Video_002_007_1  111434  111469        8     35

The 'delta' column is the result of 'Finish'-'Start'. That in addition to the following lines of code was needed to switch the x-axis from date to framewise. (At least as far as I found out)

fig_gantt.layout.xaxis.type='linear'
fig_gantt.data[0].x = df.delta.tolist()
fig_gantt.update_layout(xaxis=dict(tickmode='linear',tick0=0,dtick=50000))

I am creating the px.timeline using

fig_gantt = px.timeline(df,
                    x_start='Start', 
                    x_end='Finish',
                    y='Task',
                    width=1000,
                    height=500)
fig_gantt.update_yaxes(autorange="reversed")
fig_gantt.layout.xaxis.type='linear'
fig_gantt.data[0].x = df.delta.tolist()
fig_gantt.update_layout(xaxis=dict(tickmode='linear',tick0=0,dtick=50000))
fig_gantt.show()

This results in the following gantt chart: Gantt chart single color

When I try to add multiple colors using a dictonary and the 'Resource' column I end up having a colorful legend but no bars at all.

The Dictonary:

colors = {'0':'rgb(0,0,255)',
      '1':'rgb(0,255,0)',
      '2':'rgb(255,0,0)',
      '2b':'rgb(255,64,127)',
      '3a':'rgb(0,255,255)',
      '3b':'rgb(255,255,0)',
      '4':'rgb(127,127,127)',
      '5':'rgb(0,0,127)',
      '6':'rgb(0,127,0)',
      '7':'rgb(127,0,0)',
      '8':'rgb(0,127,127)',
      '10a':'rgb(127,127,0)',
      '10b':'rgb(64,127,255)',
      '10c':'rgb(255,127,64)',
      '12':'rgb(127,64,255)'}

My trial in adding the colors to the chart:

for i in lst:
fig_gantt = ff.create_gantt(df_timeline.loc[list_vids[i:i+1]],
                            colors=colors,
                            index_col='Resource', 
                            group_tasks=True,
                            title='Phase lengths',
                            show_colorbar=True,
                            showgrid_x=True,
                            height=200)
fig_gantt.update_yaxes(autorange="reversed")
fig_gantt.update_xaxes(type='linear')
fig_gantt.update_layout(xaxis=dict(tickmode='linear',tick0=0,dtick=4000))
fig_gantt.show()

gantt with colorful legend but without bars

So I am having one bar for each video ('Task'). Each bar includes the phases ('Resource') with the according ranges ('Start' & 'Finish') but I am failing while adding colors to get this more readable. Is there a simple solution to this problem that I am just missing or is this more complex?

I am very grateful for any help!

1 Answer 1

2

The solution is initially provided in this answer and worked for me like a charm https://stackoverflow.com/a/68842350/4165040

Just change this line:

fig_gantt.data[0].x = df.delta.tolist()

To smth like the following code (could need some tweaking because you are using custom color coding, but hope you will figure it out)

for d in fig_gantt.data:
    filt = df['Resource'] == d.name
    d.x = df[filt]['delta'].tolist()

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