Center bars of histogram using ggplot2

2019-09-10 03:11发布

问题:

I am trying to center my bars with the ggplot2 package. The bars are not aligned to the center of the corresponding value, which can lead to some misunderstanding for non-expert readers. My plot looks like this:

In order to reproduce the plot, please use the following code:

# Load data
Temp <- read.csv("http://pastebin.com/raw.php?i=mpFpjqJt", header = TRUE, stringsAsFactors=FALSE, sep = ";")
# Load package
library(ggplot2)
# Plot histogram using ggplot2
ggplot(data=Temp, aes(Temp$Score)) + 
geom_histogram(breaks=seq(0, 8, by =1), col="grey", aes(fill=..count..), binwidth = 1, origin = -0.5) 
+ scale_fill_gradient("Count", low = "green", high = "red") 
+ labs(title="Title") 
+ labs(x="X-Title", y="Y-Title") 
+ xlim(c(3,9))

How I can center each bar to the corresponding x-value?

Edit 2017-05-29 As the download link may break in the future, here are the data as returned by dput()

Temp <- structure(list(ID = 1:30, Score = c(6L, 6L, 6L, 5L, 5L, 5L, 6L, 
5L, 5L, 5L, 4L, 7L, 4L, 6L, 6L, 6L, 6L, 6L, 5L, 5L, 7L, 5L, 6L, 
5L, 5L, 5L, 4L, 6L, 6L, 5L)), .Names = c("ID", "Score"), class = "data.frame", 
row.names = c(NA, -30L))

回答1:

Just remove the breaks argument, which is redundant / in conflict with the binwidth and origin arguments:

# Load data
Temp <- read.csv("http://pastebin.com/raw.php?i=mpFpjqJt", header = TRUE, stringsAsFactors=FALSE, sep = ";")
# Load package
library(ggplot2)
# Plot histrogram using ggplo2
ggplot(data=Temp, aes(Temp$Score)) + 
  geom_histogram(col="grey", aes(fill=..count..), binwidth = 1, origin = -0.5) + 
  scale_fill_gradient("Count", low = "green", high = "red") + 
  labs(title="Title") + 
  labs(x="X-Title", y="Y-Title") + 
  xlim(c(3,9))


回答2:

Michael Kuhn's answer of Dec 2015 is returning a warning nowadays:

origin is deprecated. Please use boundary instead.

According to the release notes of version 2.1.0 of ggplot2:

You can now specify either boundary (i.e. the position of the left or right side) or the center of a bin. origin has been deprecated in favour of these arguments.

So with ggplot2version 2.1.0 and above, the suggested way forward is to use either the boundary parameter:

library(ggplot2)   # CRAN version 2.2.1 used
ggplot(data=Temp, aes(Score, fill = ..count..)) + 
  geom_histogram(col = "grey", binwidth = 1, boundary = 0.5) +
  scale_fill_gradient("Count", low = "green", high = "red") +
  labs(title = "Title") +
  labs(x = "X-Title", y = "Y-Title") +
  xlim(c(3, 9))

or the center parameter

...
geom_histogram(col = "grey", binwidth = 1, center = 0) +
...

The result is the same:

BTW: I have removed a minor flaw in OP's code which was using Temp$Score in the aes() call ggplot(data=Temp, aes(Temp$Score)) instead of ggplot(data = Temp, aes(Score)).

Data

As the download link may break in the future, here are the data as returned by dput():

Temp <- structure(list(ID = 1:30, Score = c(6L, 6L, 6L, 5L, 5L, 5L, 6L, 
5L, 5L, 5L, 4L, 7L, 4L, 6L, 6L, 6L, 6L, 6L, 5L, 5L, 7L, 5L, 6L, 
5L, 5L, 5L, 4L, 6L, 6L, 5L)), .Names = c("ID", "Score"), class = "data.frame", 
row.names = c(NA, -30L))


标签: r ggplot2