ggplot2 bar plot, no space between bottom of geom and x axis keep space above

RGgplot2

R Problem Overview


When I plot a bar graph in ggplot2 I would like to reduce the space between the bottom of the bars and the x-axis to 0, yet keep the space above the bars and the plot box. I have a hack to do it below. It's dirty and I want to be clean again. Is there a way to achieve this behavior without the dirty little hack?

Default (desired space above but don't want space below bars):

ggplot(mtcars, aes(x=as.factor(carb))) + 
    geom_bar()

enter image description here

Use expand (undesired 0 space above but got the 0 space below bars):

ggplot(mtcars, aes(x=as.factor(carb))) + 
    geom_bar() + 
    scale_y_continuous(expand = c(0,0)) 

enter image description here

Dirty Hack (I like it but its.. well, dirty):

ggplot(mtcars, aes(x=as.factor(carb))) + 
    geom_bar() + 
    scale_y_continuous(expand = c(0,0)) +
    geom_text(aes(x=1, y=10.3, label="Stretch it"), vjust=-1)

enter image description here

R Solutions


Solution 1 - R

I might be missing what you really want, but without using geom_text hack you can still set the limits

ggplot(mtcars, aes(x = as.factor(carb))) + 
    geom_bar() + 
    scale_y_continuous(expand = c(0, 0), limits = c(0, 10.3)) 

# marginally cleaner

Solution 2 - R

The R documentation includes a new convenience function called expansion for the expand argument as the expand_scale() became deprecated as of ggplot2 v3.3.0 release.

ggplot(mtcars) +
  geom_bar(aes(x = factor(carb))) + 
  scale_y_continuous(expand = expansion(mult = c(0, .1)))

Solution 3 - R

You can expand the limits manually, e.g. with expand_limits(y=10.1), or use this trick to add an invisible layer with scaled up data,

ggplot(mtcars, aes(x=as.factor(carb))) + 
    geom_bar() + 
    scale_y_continuous(expand = c(0,0)) +
    geom_blank(aes(y=1.1*..count..), stat="bin")

Solution 4 - R

Starting in ggplot2 3.0.0 there is an expand_scale() function that can be used with the expand argument to do exactly this. You define the top and bottom expansion separately.

ggplot(mtcars, aes(x=factor(carb))) + 
     geom_bar() +
     scale_y_continuous(expand = expand_scale(mult = c(0, .1)))

Solution 5 - R

Because you seem comfortable with some hardcoding...

ggplot(mtcars, aes(x = as.factor(carb))) + 
  geom_bar() +
  coord_cartesian(ylim = c(0, 10.3))

Solution 6 - R

This is an automatic way to produce the spacing at the top, yet remove the bottom spacing. I use 3 % padding since that's what you hard-coded.

plot1 <- ggplot(mtcars, aes(x=as.factor(carb))) +
    geom_bar()

plotInfo <- print(plot1)
yMax <- max(plotInfo$data[[1]]$ymax)
yLimitMax <- 1.03 * yMax

plot2 <- plot1 +
    scale_y_continuous(expand = c(0,0),
                       limits = c(0,yLimitMax))

If you want to remove the three lines between the plots, just write this in plot2 instead:

limits = c(0, 1.03 * max(print(plot1)$data[[1]]$ymax))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTyler RinkerView Question on Stackoverflow
Solution 1 - Ruser1317221_GView Answer on Stackoverflow
Solution 2 - RsamView Answer on Stackoverflow
Solution 3 - RbaptisteView Answer on Stackoverflow
Solution 4 - RaosmithView Answer on Stackoverflow
Solution 5 - RHenrikView Answer on Stackoverflow
Solution 6 - RChristianView Answer on Stackoverflow