Search code examples
pythonrexcelplotlygantt-chart

How to indicate expected dates and actual dates in a Gantt chart?


I am trying to create a Gantt chart which involves planned and actual start/end dates. I would like same tasks to overlap like:
So far this is my code.

import plotly.figure_factory as ff
import pandas as pd

df = pd.DataFrame([
    dict(Task="Job A", Start='2009-01-01', Finish='2009-02-28'),
    dict(Task="Job A", Start='2009-01-05', Finish='2009-02-15'),
    dict(Task="Job C", Start='2009-02-20', Finish='2009-05-30')
])
colors = {'Job A': 'rgb(220, 0, 0)',
          'Job C': (1, 0.9, 0.16), }

fig = ff.create_gantt(df, colors=colors, index_col="Task", show_colorbar=True, group_tasks=True)
fig.update_yaxes(autorange="reversed")  # otherwise tasks are listed from the bottom up
fig.show()

This is the result: Gantt chart without overlapping colors

How do I distinguish planned v. actual dates? Python, R and Excel solutions are welcome. Usage of Plotly in solutions is completely optional.


Solution

  • Here's an R solution:

    library(tidyverse)
    
    df %>%
      mutate(Task = factor(Task, rev(levels(factor(Task)))),
             yval = as.numeric(Task)) %>% {
      ggplot(., aes(xmin = Start, xmax = Finish)) + 
      geom_rect(data = filter(., Type == "Planned"), alpha = 0.5,
                aes(ymin = yval - 0.4, ymax = yval + 0.4, fill = "Planned")) +
      geom_rect(data = filter(., Type == "Actual"),
                aes(ymin = yval - 0.2, ymax = yval + 0.2, fill = "Actual"), 
                color = "black") +
      scale_fill_manual("", values = c("deepskyblue4", "olivedrab")) +
      scale_y_continuous(breaks = seq_along(levels(.$Task)),
                         labels = levels(.$Task)) +
      labs(title = "Planned versus actual job times", x = "Date") +
      coord_fixed(15) +
      theme_bw(base_size = 16)
    }
    

    enter image description here

    Your data should be in the following format for this:

    df
    #>    Task      Start     Finish    Type
    #> 1 Job A 2009-01-01 2009-02-28 Planned
    #> 2 Job A 2009-01-05 2009-02-15  Actual
    #> 3 Job B 2009-02-01 2009-03-15 Planned
    #> 4 Job B 2009-02-10 2009-03-15  Actual
    #> 5 Job C 2009-02-20 2009-05-30 Planned
    #> 6 Job C 2009-02-22 2009-05-20  Actual
    

    Created on 2022-05-23 by the reprex package (v2.0.1)