Annylowell
Annylowell

Reputation: 57

Plotting a barchart over a histogram in R

I am trying to overlay a histogram with a stacked barplot, yet the barplot is always shifted to the right as it starts plotting from zero. See below for an example on what I am trying to do (without using ggplot, I should maybe add).

set.seed(1)

dat <- rnorm(1000, sd = 10)
h <- hist(dat)
cnt <- h$counts
breaks <- h$breaks

mat <- matrix(NA, nrow = 3, ncol = length(cnt))
for(i in 1:length(cnt)){
  sample <- sample(1:3, size = cnt[i], replace = TRUE)
  for(j in 1:3){
    mat[j, i] <- sum(sample == j)
  }
}

barplot(mat, add = TRUE, width = unique(diff(breaks)), space = 0, 
        col = c("blue", "green", "orange"))

The output from this code looks as follow:

enter image description here

I have tried using columnnames in the matrix mat which specify the position, but to no avail. In the plot I want to create the histogram will be overplotted entirely, as it should be in the exact same place as the barplot. The reason for plotting it in the first place is that I want the axis that a histogram plot gives me. Any ideas on how to do this are very much appreciated.

Upvotes: 2

Views: 198

Answers (2)

jay.sf
jay.sf

Reputation: 72683

You may combine the bar mids of barplot console output and breaks of hist to create axis ticks; subtract half of barplot widths from the bar mids. Using mtext gives a better control for the axis labels.

h <- hist(dat, plot=FALSE)
# [...]

.width <- unique(diff(breaks))
b <- barplot(mat, width=.width, space=0, 
        col=c("blue", "green", "orange"))
axis(1, b-.width/2, labels=FALSE)
mtext(h$breaks[-length(h$breaks)], 1, 1, at=b-.width/2)

enter image description here

Edit

.width <- unique(diff(breaks))
b <- barplot(mat, width=.width, space=0, 
             col=c("blue", "green", "orange"))
ats <- seq(0, par()$usr[2], 5)
mod <- (ats + 5) %% 20 == 0
labs <- h$breaks
axis(1, ats[mod], labels=FALSE)
mtext(labs[mod], 1, 1, at=ats[mod])

enter image description here

Upvotes: 1

user12256545
user12256545

Reputation: 3002

I would just set a manual x axis to the barplot with the desired labels at the desired position, like this:

barplot(mat, width = unique(diff(breaks)),space = 0,  
        col = c("blue", "green", "orange"))
axis(1,at=c(15,35,55,75),labels = c(-20,0,20,40))


enter image description here

Upvotes: 0

Related Questions