[R] Make many barplot into one plot

Marc Schwartz marc_schwartz at comcast.net
Fri Dec 1 19:00:27 CET 2006


On Fri, 2006-12-01 at 18:02 +0100, Muhammad Subianto wrote:
> Dear all,
> ## I have 4 tables like this:
> 
> satu  <- array(c(5,15,20,68,29,54,84,119), dim=c(2,4),
>                dimnames=list(c("Negative", "Positive"), c("Black", 
> "Brown", "Red", "Blond")))
> dua   <- array(c(50,105,30,8,29,25,84,9), dim=c(2,4),
>                dimnames=list(c("Negative", "Positive"), c("Black", 
> "Brown", "Red", "Blond")))
> tiga  <- array(c(9,16,26,68,12,4,84,12), dim=c(2,4),
>                dimnames=list(c("Negative", "Positive"), c("Black", 
> "Brown", "Red", "Blond")))
> empat <- array(c(25,13,50,78,19,34,84,101), dim=c(2,4),
>                dimnames=list(c("Negative", "Positive"), c("Black", 
> "Brown", "Red", "Blond")))
> 
> ## with barplot I can make a plot for each table:
> 
> barplot(satu, beside=TRUE, legend.text=rownames(satu),
>         ylim = c(0, max(colSums(satu)) * 1.2))
> x11()
> barplot(dua, beside=TRUE, legend.text=rownames(dua),
>         ylim = c(0, max(colSums(dua)) * 1.2))
> x11()
> barplot(tiga, beside=TRUE, legend.text=rownames(tiga),
>         ylim = c(0, max(colSums(tiga)) * 1.2))
> x11()
> barplot(empat, beside=TRUE, legend.text=rownames(empat),
>         ylim = c(0, max(colSums(empat)) * 1.2))
> 
> ## I can make all barplot above into one plot with
> 
> x11(width=11,height=8)
> ## Make a plot with 2 rows and 2 columns
> oldpar <- par(mfrow=c(2,2),
>    barplot(above)
> par(oldpar)
> 
> ## Are there any functions to make all barplot above into one plot?
> ## I would like to produce barplot like:
> 
> |   |                               |   |
> |   |   |   |   |   |   |   |   |   |   |   |   |   |
> |pos|neg|pos|neg|pos|neg|pos|neg|   |pos|neg|pos|neg| ...
> |   |   |   |   |   |   |   |   |   |   |   |   |   |
> ---------------------------------   --------------------
>   satu     dua     tiga   empat        satu    dua ...
>               black                         blond
> 
> I would be grateful if anybody could help me.
> Thank you very much.

I would encourage you to look at the barchart() function in the lattice
package, which in many ways is better suited to doing multi-dimensional
plots.

That being said:

# rbind() the tables together
TAB <- rbind(satu, dua, tiga, empat)

# Do the barplot and save the bar midpoints
mp <- barplot(TAB, beside = TRUE,
              axisnames = FALSE)

# Add the individual bar labels
mtext(1, at = mp, text = c("N", "P"),
      line = 0, cex = 0.5)

# Get the midpoints of each sequential pair of bars
# within each of the four groups
at <- t(sapply(seq(1, nrow(TAB), by = 2),
               function(x) colMeans(mp[c(x, x+1), ])))

# Add the group labels for each pair
mtext(1, at = at,
      text = rep(c("satu", "dua", "tiga", "empat"), 4),
      line = 1, cex = 0.75)

# Add the color labels for each group
mtext(1, at = colMeans(mp),
      text = c("Black", "Brown", "Red", "Blond"),
      line = 2)


Take a look at ?barplot and note that the function returns the bar
midpoints, which in this case is a matrix:

> mp
     [,1] [,2] [,3] [,4]
[1,]  1.5 10.5 19.5 28.5
[2,]  2.5 11.5 20.5 29.5
[3,]  3.5 12.5 21.5 30.5
[4,]  4.5 13.5 22.5 31.5
[5,]  5.5 14.5 23.5 32.5
[6,]  6.5 15.5 24.5 33.5
[7,]  7.5 16.5 25.5 34.5
[8,]  8.5 17.5 26.5 35.5


Then look at ?mtext for the labelling.

HTH,

Marc Schwartz




More information about the R-help mailing list