Simplified Guide to geom_crossbar for Gantt Charts

The geom_crossbar function in the ggplot2 package is useful for showing ranges and central points like the median or mean. Also, it can be used to make Gantt charts. Gantt charts are mainly used in project management to show task schedules and progress. They display the start and end times and durations of tasks with bars.

Getting Started with geom_crossbar

Before creating a Gantt chart, let’s explore how the graph is drawn using geom_crossbar. I’ve set up some random numbers to draw five bars.

tb1 = tibble(x = c(0, 4, 5, 10, 11), 
             y = c("A", "B", "C", "D", "E"), 
             se = c(2,3,4,4,3))
tb1$y = factor(tb1$y, levels = rev(unique(tb1$y)))

geom_crossbar needs more than just x and y values – it also needs min and max values. You don’t have to set both x and y axes; you can just focus on one. When you draw it, there’s a middle line, and on either side, you’ll see bars representing the range between the min and max values.

ggplot(tb1) +
  geom_crossbar(aes(x = x, y = y, 
                    xmin = x - se, 
                    xmax = x + se))

For example, if you set the x value to -5, when you draw it, you’ll notice that the central line is drawn outside the bar graph.

ggplot(tb1) +
  geom_crossbar(aes(x = x - 5, y = y, 
                    xmin = x - se, 
                    xmax = x + se))

However, the Gantt chart I’m trying to create doesn’t require this central line. So, setting the “fatten” value to 0 makes the thickness of the central line 0, causing it to disappear.

ggplot(tb1) +
  geom_crossbar(aes(x = x, y = y, 
                    xmin = x - se, 
                    xmax = x + se), fatten = 0)

Creating a Gantt Chart

To create a Gantt chart, I’ve generated some random project schedule data. I converted it to a factor to reverse the bar alignment on the y-axis.

v_grp = c("Planning", "Research", "Design", "Review", "Develop")
tb2 = tibble(grp = v_grp, 
                 xmin = c(0,4,4, 10, 14), 
                 xmax = c(7,10,20,20,20)) |> 
  mutate(grp = factor(grp, levels = rev(v_grp)))

Now that the data is ready, you can simply use geom_crossbar to draw the Gantt chart. Since the central line is unnecessary for a Gantt chart, I removed it by setting fatten = 0.

ggplot() +
  geom_crossbar(aes(y = grp, x = xmin, xmin = xmin, xmax = xmax), 
                data = tb2, fill = "#A5D7FB", fatten = 0, width = 0.3, colour = NA)

To make the graph more interesting and highlight certain parts of the schedule, I added extra data and drew additional bars in a different color on top.

tb3 = tibble(grp = c("Design", "Review"), 
             xmin = c(4, 10), 
             xmax = c(13,15)) |> 
  mutate(grp = factor(grp, levels = rev(v_grp)))

ggplot() +
  geom_crossbar(aes(y = grp, x = xmin, xmin = xmin, xmax = xmax), 
                data = tb2, fill = "#A5D7FB", fatten = 0, width = 0.3, colour = NA) +
  geom_crossbar(aes(y = grp, x = xmin, xmin = xmin, xmax = xmax), 
                data = tb3, fill = "#4295E4", fatten = 0, width = 0.3, colour = NA)

Cleaning up unnecessary lines and adding color, the design can be completed as shown below. It might be interesting to try making one with a more complex schedule, but for now, this simple concept should be enough.


See also