3.7 Making a Stacked Bar Graph

3.7.1 Problem

You want to make a stacked bar graph.

3.7.2 Solution

Use geom_bar() and map a variable fill. This will put Date on the x-axis and use Cultivar for the fill color, as shown in Figure 3.16:

library(gcookbook) # Load gcookbook for the cabbage_exp data set

ggplot(cabbage_exp, aes(x = Date, y = Weight, fill = Cultivar)) +
  geom_col()
#> This is an untitled chart with no subtitle or caption.
#> It has x-axis 'Date' with labels d16, d20 and d21.
#> It has y-axis 'Weight' with labels 0, 2, 4 and 6.
#> There is a legend indicating fill is used to show Cultivar, with 2 levels:
#> c39 shown as strong reddish orange fill and 
#> c52 shown as brilliant bluish green fill.
#> The chart is a bar chart with 6 vertical bars.
#> Bar 1 is centered horizontally at d16, and spans vertically from 2.26 to 5.44 with fill colour strong reddish orange which maps to Cultivar = c39.
#> Bar 2 is centered horizontally at d20, and spans vertically from 3.11 to 5.91 with fill colour strong reddish orange which maps to Cultivar = c39.
#> Bar 3 is centered horizontally at d21, and spans vertically from 1.47 to 4.21 with fill colour strong reddish orange which maps to Cultivar = c39.
#> Bar 4 is centered horizontally at d16, and spans vertically from 0 to 2.26 with fill colour brilliant bluish green which maps to Cultivar = c52.
#> Bar 5 is centered horizontally at d20, and spans vertically from 0 to 3.11 with fill colour brilliant bluish green which maps to Cultivar = c52.
#> Bar 6 is centered horizontally at d21, and spans vertically from 0 to 1.47 with fill colour brilliant bluish green which maps to Cultivar = c52.
#> These are stacked, as sorted by Cultivar.
Stacked bar graph

Figure 3.16: Stacked bar graph

3.7.3 Discussion

To understand how the graph is made, it’s useful to see how the data is structured. There are three levels of Date and two levels of Cultivar, and for each combination there is a value for Weight:

cabbage_exp
#>   Cultivar Date Weight        sd  n         se
#> 1      c39  d16   3.18 0.9566144 10 0.30250803
#> 2      c39  d20   2.80 0.2788867 10 0.08819171
#> 3      c39  d21   2.74 0.9834181 10 0.31098410
#> 4      c52  d16   2.26 0.4452215 10 0.14079141
#> 5      c52  d20   3.11 0.7908505 10 0.25008887
#> 6      c52  d21   1.47 0.2110819 10 0.06674995

By default, the stacking order of the bars is the same as the order of items in the legend. For some data sets it might make sense to reverse the order of the legend. To do this, you can use the guides function and specify which aesthetic for which the legend should be reversed. In this case, it’s fill:

ggplot(cabbage_exp, aes(x = Date, y = Weight, fill = Cultivar)) +
  geom_col() +
  guides(fill = guide_legend(reverse = TRUE))
#> This is an untitled chart with no subtitle or caption.
#> It has x-axis 'Date' with labels d16, d20 and d21.
#> It has y-axis 'Weight' with labels 0, 2, 4 and 6.
#> There is a legend indicating fill is used to show Cultivar, with 2 levels:
#> c39 shown as strong reddish orange fill and 
#> c52 shown as brilliant bluish green fill.
#> The chart is a bar chart with 6 vertical bars.
#> Bar 1 is centered horizontally at d16, and spans vertically from 2.26 to 5.44 with fill colour strong reddish orange which maps to Cultivar = c39.
#> Bar 2 is centered horizontally at d20, and spans vertically from 3.11 to 5.91 with fill colour strong reddish orange which maps to Cultivar = c39.
#> Bar 3 is centered horizontally at d21, and spans vertically from 1.47 to 4.21 with fill colour strong reddish orange which maps to Cultivar = c39.
#> Bar 4 is centered horizontally at d16, and spans vertically from 0 to 2.26 with fill colour brilliant bluish green which maps to Cultivar = c52.
#> Bar 5 is centered horizontally at d20, and spans vertically from 0 to 3.11 with fill colour brilliant bluish green which maps to Cultivar = c52.
#> Bar 6 is centered horizontally at d21, and spans vertically from 0 to 1.47 with fill colour brilliant bluish green which maps to Cultivar = c52.
#> These are stacked, as sorted by Cultivar.
Stacked bar graph with reversed legend order

Figure 3.17: Stacked bar graph with reversed legend order

If you’d like to reverse the stacking order of the bars, as in Figure 3.18, use position_stack(reverse = TRUE). You’ll also need to reverse the order of the legend for it to match the order of the bars:

ggplot(cabbage_exp, aes(x = Date, y = Weight, fill = Cultivar)) +
  geom_col(position = position_stack(reverse = TRUE)) +
  guides(fill = guide_legend(reverse = TRUE))
#> This is an untitled chart with no subtitle or caption.
#> It has x-axis 'Date' with labels d16, d20 and d21.
#> It has y-axis 'Weight' with labels 0, 2, 4 and 6.
#> There is a legend indicating fill is used to show Cultivar, with 2 levels:
#> c39 shown as strong reddish orange fill and 
#> c52 shown as brilliant bluish green fill.
#> The chart is a bar chart with 6 vertical bars.
#> Bar 1 is centered horizontally at d16, and spans vertically from 0 to 3.18 with fill colour strong reddish orange which maps to Cultivar = c39.
#> Bar 2 is centered horizontally at d20, and spans vertically from 0 to 2.8 with fill colour strong reddish orange which maps to Cultivar = c39.
#> Bar 3 is centered horizontally at d21, and spans vertically from 0 to 2.74 with fill colour strong reddish orange which maps to Cultivar = c39.
#> Bar 4 is centered horizontally at d16, and spans vertically from 3.18 to 5.44 with fill colour brilliant bluish green which maps to Cultivar = c52.
#> Bar 5 is centered horizontally at d20, and spans vertically from 2.8 to 5.91 with fill colour brilliant bluish green which maps to Cultivar = c52.
#> Bar 6 is centered horizontally at d21, and spans vertically from 2.74 to 4.21 with fill colour brilliant bluish green which maps to Cultivar = c52.
#> These are stacked, as sorted by Cultivar.
Stacked bar graph with reversed stacking order

Figure 3.18: Stacked bar graph with reversed stacking order

It’s also possible to modify the column of the data frame so that the factor levels are in a different order (see Recipe ??). Do this with care, since the modified data could change the results of other analyses.

For a more polished graph, we’ll use scale_fill_brewer() to get a different color palette, and use colour="black" to get a black outline (Figure 3.19):

ggplot(cabbage_exp, aes(x = Date, y = Weight, fill = Cultivar)) +
  geom_col(colour = "black") +
  scale_fill_brewer(palette = "Pastel1")
#> This is an untitled chart with no subtitle or caption.
#> It has x-axis 'Date' with labels d16, d20 and d21.
#> It has y-axis 'Weight' with labels 0, 2, 4 and 6.
#> There is a legend indicating fill is used to show Cultivar, with 2 levels:
#> c39 shown as vivid pink fill and 
#> c52 shown as very pale blue fill.
#> The chart is a bar chart with 6 vertical bars.
#> Bar 1 is centered horizontally at d16, and spans vertically from 2.26 to 5.44 with fill colour vivid pink which maps to Cultivar = c39.
#> Bar 2 is centered horizontally at d20, and spans vertically from 3.11 to 5.91 with fill colour vivid pink which maps to Cultivar = c39.
#> Bar 3 is centered horizontally at d21, and spans vertically from 1.47 to 4.21 with fill colour vivid pink which maps to Cultivar = c39.
#> Bar 4 is centered horizontally at d16, and spans vertically from 0 to 2.26 with fill colour very pale blue which maps to Cultivar = c52.
#> Bar 5 is centered horizontally at d20, and spans vertically from 0 to 3.11 with fill colour very pale blue which maps to Cultivar = c52.
#> Bar 6 is centered horizontally at d21, and spans vertically from 0 to 1.47 with fill colour very pale blue which maps to Cultivar = c52.
#> These are stacked, as sorted by Cultivar.
#> It has colour set to black.
Stacked bar graph with reversed legend, new palette, and black outline

Figure 3.19: Stacked bar graph with reversed legend, new palette, and black outline

3.7.4 See Also

For more on using colors in bar graphs, see Recipe 3.4.

To reorder the levels of a factor based on the values of another variable, see Recipe ??. To manually change the order of factor levels, see Recipe ??.