I am trying to use the timeline chart show each row (Y-axis) with different heights in below chart. Code:
import plotly.express as px
import pandas as pd
df = pd.DataFrame([dict(Task="Task1", Start='2017-01-01', Finish='2017-02-15', Phase ='Phase1', Height=0.50),
dict(Task="Task1", Start='2017-02-15', Finish='2017-03-15', Phase ='Phase2', Height=0.50),
dict(Task="Task2", Start='2017-01-17', Finish='2017-02-17', Phase ='Phase2', Height=0.2),
dict(Task="Task2", Start='2017-02-18', Finish='2017-03-17', Phase ='Phase3', Height=0.20),
dict(Task="Task3", Start='2017-03-10', Finish='2017-03-31', Phase ='Phase1', Height=1.0),
dict(Task="Task3", Start='2017-04-01', Finish='2017-05-20', Phase ='Phase2', Height=1.0),
dict(Task="Task3", Start='2017-05-18', Finish='2017-06-18', Phase ='Phase3', Height=1.0),
dict(Task="Task4", Start='2017-01-14', Finish='2017-03-14', Phase ='Phase4', Height=0.4)])
colors = {'Shadow': 'rgb(237, 125, 49)','Rev Shadow': 'rgb(0, 255, 100)', 'KA': 'rgb(68, 114, 196)', 'Enablement': 'rgb(150, 150, 150)'}
fig = px.timeline(df, y = 'Task', x_start='Start', x_end = 'Finish', color= 'Phase',
color_discrete_sequence=px.colors.qualitative.D3)
fig.update_layout(autosize=False, width=800, height=300)
fig.show()
Timeline chart with correct colors, but same height
Can you please help on how to increase/decrease the height of each of the bars. Note that all individual bars in a row (Task) will be of same height. Also, I can change the color parameter in px.timeline to 'Task' and run the below command, which will change the 'Heights' the way I want. But, this will make the whole row (Task) with the same color. I get the heights I want, but not the colors in this case...
Please help and thanks in advance !!
fig = px.timeline(df, y = 'Task', x_start='Start', x_end = 'Finish', color= 'Task',
color_discrete_sequence=px.colors.qualitative.D3)
fig.update_layout(autosize=False, width=800, height=300)
for i, d in enumerate(fig.data):
d.width = df[df['Task']==d.name]['Height']
Timeline chart with correct height, but same color for each task
I was able to use broken barh in matplotlib which can do what I was looking for. Hope it helps if anyone else has similar issue. Cant be done using plotly express though.
import pandas as pd
import matplotlib.pyplot as plt
fig, gnt = plt.subplots()
df = pd.DataFrame([dict(Task="Task1", Start='2017-01-01', Finish='2017-02-15', Phase ='Phase1', Height=0.5),
dict(Task="Task1", Start='2017-02-15', Finish='2017-03-15', Phase ='Phase2', Height=0.5),
dict(Task="Task2", Start='2017-01-17', Finish='2017-02-17', Phase ='Phase2', Height=0.2),
dict(Task="Task2", Start='2017-02-18', Finish='2017-03-17', Phase ='Phase3', Height=0.2),
dict(Task="Task3", Start='2017-03-10', Finish='2017-03-31', Phase ='Phase1', Height=0.9),
dict(Task="Task3", Start='2017-04-01', Finish='2017-05-20', Phase ='Phase2', Height=0.9),
dict(Task="Task3", Start='2017-05-18', Finish='2017-06-18', Phase ='Phase3', Height=0.9),
dict(Task="Task4", Start='2017-01-14', Finish='2017-03-14', Phase ='Phase4', Height=0.4)])
df['Start']= pd.to_datetime(df['Start'])
df['Finish']= pd.to_datetime(df['Finish'])
colors = pd.DataFrame([('Phase1', 'tab:brown', 0), ('Phase2', 'tab:blue', 0),
('Phase3', 'tab:orange', 0),('Phase4', 'tab:green', 0)],
columns = ['Phase', 'Color', 'LegendUse'])
bar_height = pd.DataFrame([('Task1', 0.5), ('Task2', 0.2), ('Task3', 0.9), ('Task4', 0.4)],
columns = ['Task', 'Height'])
for i in df.index:
if colors.loc[colors['Phase'] == df.Phase[i], 'LegendUse'].iloc[0] == 0:
colors.loc[colors['Phase'] == df.Phase[i], 'LegendUse'] = 1
prefix = ''
else:
prefix = '_'
thisbar = float(bar_height.loc[bar_height.Task == df.Task[i]].Height)
thisYaxis = int(bar_height.loc[bar_height.Task == df.Task[i]].index[0])
thiscolor = colors.loc[colors['Phase'] == df.Phase[i], 'Color'].iloc[0]
gnt.broken_barh([(df.Start[i], (df.Finish[i] - df.Start[i]))], (thisYaxis, thisbar),
facecolors=(thiscolor), label = prefix+df.Phase[i])
plt.legend(loc='upper left', bbox_to_anchor=(1.01, 1))
gnt.axes.get_yaxis().set_ticks([])
gnt.set_xticklabels(pd.date_range(start="2017-01-01",end="2017-07-01",freq = 'M').strftime('%b %Y'))
fig.set_figheight(4)
fig.set_figwidth(15)
fig.show()