10

For layouting reasons I would like to position the histgram bars centered on the labels, such that the middle of a bar is on top of the label.

library(ggplot2)

df <- data.frame(x = c(0,0,1,2,2,2))

ggplot(df,aes(x)) + 
    geom_histogram(binwidth=1) + 
    scale_x_continuous(breaks=0:2)

This is what it looks so far - the left side of a bar is on top of the label:

enter image description here

Is it possible to adjust the given snippet in such a way? (without using geom_bar instead f.x.)

Raffael
  • 19,547
  • 15
  • 82
  • 160

3 Answers3

20

This doesn't require a categorical x axis, but you'll want to play a little if you have different bin widths than 1.

library(ggplot2)

df <- data.frame(x = c(0,0,1,2,2,2))

ggplot(df,aes(x)) + 
geom_histogram(binwidth=1,boundary=-0.5) + 
scale_x_continuous(breaks=0:2)

For older ggplot2 (<2.1.0), use geom_histogram(binwidth=1, origin=-0.5).

colcarroll
  • 3,632
  • 17
  • 25
  • The `origin` parameter has now been depreciated in favor of `boundary`. You will need to use that if you are using `ggplot2` 2.1 or above. – niczky12 Aug 31 '16 at 07:59
8

Here is one option: Calculate your own y-values, use x as a categorical x-axis and use geom_bar(stat="identity").

library(ggplot2)
library(data.table)

df = data.table(x = c(0,0,1,2,2,2))

df = df[, .N, by=x]

p = ggplot(df, aes(x=factor(x), y=N)) +
    geom_bar(stat="identity", width=1.0)

ggsave("barplot.png", p, width=8, height=4, dpi=120)

enter image description here

bdemarest
  • 14,397
  • 3
  • 53
  • 56
  • sorry, but you introduced unnecessarily a new package and ignored my request to not resort to geom_bar. please adjust or delete your answer. thanks – Raffael Nov 15 '13 at 09:25
5

The code immediately below used to work but no longer. It was preventing ggplot from assuming that bins can be evenly divided (but now ggplot2::geom_hiustogram catches this subterfuge and suggests using a different function:

ggplot(df,aes( factor(x) )) + 
    geom_histogram(binwidth=1 )
#Error: StatBin requires a continuous x variable the x variable is discrete. Perhaps you want stat="count"?

So instead use:

ggplot(df,aes( factor(x) )) + 
    stat_count ()
IRTFM
  • 258,963
  • 21
  • 364
  • 487