0

I am working on a Gantt chart to track project tasks progress using Plotly. I want to create a chart that would depict each Task as a bar in Gantt chart and the bar should be shaded according to the percentage complete value

The existing code that I have is as follows: `

fig = ff.create_gantt(df,index_col='Team_Name', colors = color_dict, 
                      show_colorbar=True, showgrid_x = True, showgrid_y = False,
                      title = 'Project XYZ Tracker')
fig.update_yaxes(autorange='reversed')

` This code gives me a Gantt chart as shown in this link: Gantt Chart generated using the plotly code above

I want the bars in the Gantt chart to look as shown in this link: Expected format of Bars (with percentage complete on the side, color, shading and opacity in the Gantt Chart

The data I am using is as shown in this link: Dataframe with sample data

Div
  • 11
  • 2
  • 1
    Welcome to [SO]. This is not a code-writing or tutoring service. We help solve specific problem with code you are writing, not open-ended requests for code or advice. Please edit your question to show what you have tried so far, and what specific problem you need help with. See the [what you are asking] page for details on how to best help us help you. **DO NOT** post images of code, links to code, data, error messages, etc. - copy or type the text into the question. – itprorh66 Mar 29 '23 at 23:37
  • You can refer to this thread for how to create and post reproducible sample data: [How to make good reproducible pandas examples](https://stackoverflow.com/questions/20109391). – AlexK Mar 30 '23 at 01:21
  • @Div posting images of dataframes is discouraged because we can't copy and paste it easily (which makes it time consuming to try to reproduce your charts). can you instead copy and paste the output from `df.head().to_dict()` directly into the question? thanks! – Derek O Mar 30 '23 at 01:50

1 Answers1

0

I don't understand the need for the expected graph requirement, but my approach is to use transparency to overlay the same task with scheduled and actual results. I took the end date of the data you presented as scheduled and added a progress date. px.timeline() is used to create a graph of scheduled vs. actual. This chart data is reused and set as a bar chart in the graph_object. Layout information is also reused and set. My response was to overlay the timeline and annotate the progress rate. Make duplicate legend elements unique.

import pandas as pd
import datetime
import plotly.express as px
import plotly.graph_objects as go

df['Start_Date'] = pd.to_datetime(df['Start_Date'])
df['End_Date'] = pd.to_datetime(df['End_Date'])
df['End_Date2'] = df[['Percentage_complete', 'Start_Date','End_Date']].apply(lambda x: (x[2]-x[1])*x[0]+x[1], axis=1)

fig1 = px.timeline(df, x_start="Start_Date", x_end="End_Date", y="Task_Name", color='Team_Name', opacity=0.5)
fig2 = px.timeline(df, x_start="Start_Date", x_end="End_Date2", y="Task_Name", color='Team_Name')

fig = go.Figure()
fig.add_trace(go.Bar(fig1.data[0]))
fig.add_trace(go.Bar(fig1.data[1]))
fig.add_trace(go.Bar(fig1.data[2]))
fig.add_trace(go.Bar(fig1.data[3]))
fig.add_trace(go.Bar(fig2.data[0]))
fig.add_trace(go.Bar(fig2.data[1]))
fig.add_trace(go.Bar(fig2.data[2]))
fig.add_trace(go.Bar(fig2.data[3]))

for row in df.itertuples():
    fig.add_annotation(xref='x', yref='y',
                   x=row.End_Date+datetime.timedelta(days=1),
                   y=row.Task_Name,
                       showarrow=False,
                   text='{:.0%}'.format(row.Percentage_complete)
                  )
names = set()
fig.for_each_trace(
    lambda trace:
        trace.update(showlegend=False)
        if (trace.name in names) else names.add(trace.name))

fig.update_layout(fig1.layout)
fig.update_yaxes(autorange="reversed")

fig.show()

enter image description here

r-beginners
  • 31,170
  • 3
  • 14
  • 32