25

I understand that one can change the width of a bar in geom_bar using the width argument. That does work, but then it creates a larger gap between the bars. Is there a way to manually push the bars closer to together? Should I be manipulating the axis somehow instead?

Here is an example, changing width to 0.3 on the right to get the desired bar width.

library(tidyverse)
library(gridExtra)

p1 <- ggplot(iris, aes(Species, Petal.Length)) + geom_bar(stat="summary")
p2 <- ggplot(iris, aes(Species, Petal.Length)) + geom_bar(stat="summary", width=0.3)
grid.arrange(p1,p2,nrow=1)

enter image description here

Note: I know this question is similar to this one, but the answer to closing the gap was not apparent.

How to change the space between bars in geom_bar?

Alex
  • 779
  • 2
  • 7
  • 20
  • What have you tried so far? Perhaps, you want to look at this [post](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) to learn how to provide a reproducible example. – mnm Apr 28 '18 at 14:05
  • 2
    I tried changing the width, as described. Is a reproducible example really necessary here? This is a question about a basic feature of ggplot2, not something idiosyncratic to whatever code I'm using. – Alex Apr 28 '18 at 14:10
  • Sounds like you want to reduce the overall width of the x-axis. Maybe consider something like `p1 + coord_fixed(ratio = 0.02)`? – Z.Lin Apr 28 '18 at 14:35
  • @Alex, have you seen this [post](https://stackoverflow.com/questions/31458536/increase-space-between-bars-in-ggplot)? It mentions about `position_dodge()` – mnm Apr 28 '18 at 14:36
  • 2
    I don't think this is a bad question - in fact, I haven't seen this answered to my own satisfaction yet. Also, with the addition of the reproducible code, there's no call for a negative rating on the question. – Dannid Feb 26 '19 at 20:17

3 Answers3

25

I would adjust the plot's aspect ratio, and have ggplot automatically assign the right width for the bars and the gap between them:

  ggplot(iris, aes(Species, Petal.Length)) + 
      geom_bar(stat="summary", width=0.4) +
      theme(aspect.ratio = 2/1)

Produces this:

enter image description here

onlyphantom
  • 8,606
  • 4
  • 44
  • 58
5

Rather than taking the width smaller, which narrows the bars but increases the inter-bar space, set width = 1 to remove all space between.*

ggplot(iris, aes(Species, Petal.Length, fill=Species)) + geom_bar(stat="summary", width=1)

enter image description here

The default value is 0.9, so you can get very small spaces by setting width = 0.95

ggplot(iris, aes(Species, Petal.Length, fill=Species)) + geom_bar(stat="summary", width=0.95)

enter image description here

  • With fill=Species, I took the liberty of adding color to help see the different bars when there is no space between.
Dannid
  • 1,507
  • 1
  • 20
  • 17
  • 7
    This does not really answer the question as OP want to specifically reduce the gap size, not just mask them with wider bars. – Lamma Aug 26 '20 at 11:51
  • This helped me today, Thank you `width=1` is quite handy – amrrs Mar 31 '22 at 06:19
  • @Lamma The OP seemed to be asking for a way to bring the bars closer together. One interpretation is that they wanted skinnier bars. I provided an alternative interpretation of just removing the space in between. I haven't found a way to do both at the same time, however (skinny bars with no gap in between). Maybe some scaling to the final plot? – Dannid Aug 25 '22 at 17:58
0

I ended up trying to figure out this problem while attempting to compare two plots, one with many groups of bars and the other with only one group, so instead of presenting two graphs with bars of different width produced by

library(patchwork)

ds <- iris %>% dplyr::mutate(Has.Large.Sepal = Sepal.Length > 5)

p1 <- ggplot(ds, aes(x = Species, y = Petal.Length, fill = Has.Large.Sepal)) +
      geom_bar(stat = "summary", position = "dodge")
p2 <- ggplot(ds %>% filter(Has.Large.Sepal == TRUE), aes(x = Species, y = Petal.Width)) + 
      geom_bar(stat = "summary", position = "dodge", fill = "#00BFC4")

p1 + p2

Which yields (note that the blue color on the legend apply to both graphs because I am filtering ds in the second plot to only include individuals with Has.Large.Sepal == TRUE) enter image description here

I shrinked the second bar with the help of patchwork to make the bars' width similar in size to those of my previous plot

p2 <- ggplot(ds %>% filter(Has.Large.Sepal == TRUE), aes(x = Species, y = Petal.Width)) + 
  geom_bar(stat = "summary", position = "dodge", fill = "#00BFC4", width = .95) + 
  theme(axis.text.x = element_text(angle = 90))

p1 + (p2 + plot_spacer())

Obtaining a more comparable pair of plots

enter image description here

terraviva
  • 11
  • 4