Add space above y-axis without expand()

Viewed 1255

When plotting percentages and a column is at 100%, the value label gets cut of from the graph.

enter image description here

Two possible solutions to this are:
1. scale_y_continuous(limits = c(0, 1.1)
2. scale_y_continuous(expand = c(0, 0, 0.2, 0)
But both solutions expand the axis. I would prefer to just add a padding/margin so that I don't get a long line above 100%. Is this possible? enter image description here

Working example

library(ggplot2)
library(magrittr)
data.frame("value" = c(0, 0.5, 1),
           "v1" = letters[1:3]) %>% 
        ggplot(aes(x = v1, 
                   y = value, 
                   label = value)) +
        geom_bar(stat = "identity") + 
        geom_text(stat = "identity",
                  vjust = -1) + 
        scale_y_continuous(breaks = seq(0, 1, 0.2), 
                           limits = c(0, 1),
                           labels = scales::percent, 
                           expand = c(0, 0, 0.2, 0)) + 
        theme_classic()
2 Answers

You can pad the plot with plot.margin argument in the theme function and turn off clipping in coord_cartesian to allow for drawings to be unconfined to the plot panel.

data.frame("value" = c(0, 0.5, 1),
           "v1" = letters[1:3]) %>% 
  ggplot(aes(x = v1, 
             y = value, 
             label = value)) +
  geom_bar(stat = "identity") + 
  geom_text(stat = "identity",
            vjust = -1) + 
  scale_y_continuous(breaks = seq(0, 1, 0.2), 
                     limits = c(0, 1),
                     labels = scales::percent) + 
  theme_classic() +
  theme(plot.margin = margin(t = 10, unit = "pt")) + ## pad "t"op region of the plot
  coord_cartesian(clip = "off")

enter image description here

Probably worth noting as well this is only an issue when you want a wide plot.

An alternate approach is to limit the extension of axes' lines. This is implemented in the package lemon, which also allows you to place square brackets for each tick instead of a single line for the axis:

library(ggplot2)

df <- data.frame("value" = c(0, 0.5, 1),
           "v1" = letters[1:3])

p <- ggplot(df, aes(x = v1, 
                   y = value, 
                   label = value)) +
        geom_bar(stat = "identity") + 
        geom_text(stat = "identity",
                  vjust = -1) + 
        scale_y_continuous(breaks = seq(0, 1, 0.2), 
                           limits = c(0, 1),
                           labels = scales::percent,
                           expand = rep(0,4)) +
        theme_classic()

library(lemon)
p + coord_flex_cart(ylim=c(-0.01, 1.1), left=capped_vertical(capped='both', gap=0.0),
  bottom = brackets_horizontal())

enter image description here

The length of the brackets can be modified with arguments length and tick.length.

Related