3.5 Coloring Negative and Positive Bars Differently

3.5.1 Problem

You want to use different colors for negative and positive-valued bars.

3.5.2 Solution

We’ll use a subset of the climate data and create a new column called pos, which indicates whether the value is positive or negative:

library(gcookbook) # Load gcookbook for the climate data set
library(dplyr)

climate_sub <- climate %>%
  filter(Source == "Berkeley" & Year >= 1900) %>%
  mutate(pos = Anomaly10y >= 0)

climate_sub
#>       Source Year Anomaly1y Anomaly5y Anomaly10y Unc10y   pos
#> 1   Berkeley 1900        NA        NA     -0.171  0.108 FALSE
#> 2   Berkeley 1901        NA        NA     -0.162  0.109 FALSE
#> 3   Berkeley 1902        NA        NA     -0.177  0.108 FALSE
#>  ...<99 more rows>...
#> 103 Berkeley 2002        NA        NA      0.856  0.028  TRUE
#> 104 Berkeley 2003        NA        NA      0.869  0.028  TRUE
#> 105 Berkeley 2004        NA        NA      0.884  0.029  TRUE

Once we have the data, we can make the graph and map pos to the fill color, as in Figure 3.11. Notice that we use position=“identity” with the bars. This will prevent a warning message about stacking not being well defined for negative numbers:

ggplot(climate_sub, aes(x = Year, y = Anomaly10y, fill = pos)) +
  geom_col(position = "identity")
#> This is an untitled chart with no subtitle or caption.
#> It has x-axis 'Year' with labels 1920, 1950 and 1980.
#> It has y-axis 'Anomaly10y' with labels 0.0 and 0.5.
#> There is a legend indicating fill is used to show pos, with 2 levels:
#> FALSE shown as strong reddish orange fill and 
#> TRUE shown as brilliant bluish green fill.
#> The chart is a bar chart with 105 vertical bars.
Different colors for positive and negative values

Figure 3.11: Different colors for positive and negative values

3.5.3 Discussion

There are a few problems with the first attempt. First, the colors are probably the reverse of what we want: usually, blue means cold and red means hot. Second, the legend is redundant and distracting.

We can change the colors with scale_fill_manual() and remove the legend with guide = FALSE, as shown in Figure 3.12. We’ll also add a thin black outline around each of the bars by setting colour and specifying size, which is the thickness of the outline (in millimeters):

ggplot(climate_sub, aes(x = Year, y = Anomaly10y, fill = pos)) +
  geom_col(position = "identity", colour = "black", size = 0.25) +
  scale_fill_manual(values = c("#CCEEFF", "#FFDDDD"), guide = FALSE)
#> Warning: It is deprecated to specify `guide = FALSE` to remove a guide.
#> Please use `guide = "none"` instead.
#> This is an untitled chart with no subtitle or caption.
#> It has x-axis 'Year' with labels 1920, 1950 and 1980.
#> It has y-axis 'Anomaly10y' with labels 0.0 and 0.5.
#> In this chart fill is used to show pos. The legend that would normally indicate this has been hidden.
#> The chart is a bar chart with 105 vertical bars.
#> It has colour set to black.
#> It has size set to 0.25.
Graph with customized colors and no legend

Figure 3.12: Graph with customized colors and no legend

3.5.4 See Also

To change the colors used, see Recipes Recipe ?? and Recipe ??.

To hide the legend, see Recipe ??.