File: drawNestedBars.R

package info (click to toggle)
r-cran-plotrix 2.9-3-2
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 960 kB
  • sloc: makefile: 3
file content (80 lines) | stat: -rw-r--r-- 2,924 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
drawNestedBars<-function(x,start,end,shrink=0.1,errbars=FALSE,
 col=NA,labelcex=1,labely=NA,showbars=TRUE,showlabels=TRUE,arrow.cap=0.01) {

 dimx<-dim(x[[1]])
 if(is.null(dimx) || length(dimx) == 1) {
  # this is the final level
  lenx<-length(x[[1]])
  # assume start and end are the edges of the bar within which
  # the new bars must fit. First calculate the total space
  barspace<-(end-start)*shrink
  # then calculate the width of each bar
  barwidth<-((end-start)-barspace)/lenx
  # calculate the space between bars and at the edges
  barspace<-barspace/(lenx+1)
  start<-start+barspace
  arrow.gap<-strheight("O")/2
  caplen<-arrow.cap*par("pin")[1]
  barlabels<-x[[4]]
  if(length(col) < lenx) col<-rep(col,length.out=lenx)
  for(xbar in 1:lenx) {
   barcenter<-start+barwidth/2
   if(!is.null(x[[1]][[xbar]]) && showbars)
    rect(start,0,start+barwidth,x[[1]][[xbar]],col=col[xbar])
   if(errbars) {
    if(!is.null(x[[2]][[xbar]]) && !is.null(x[[3]][[xbar]]) &&
       !is.na(x[[2]][[xbar]]) && !is.na(x[[3]][[xbar]])) {
     if(arrow.gap >= x[[2]][[xbar]] * 0.9 || arrow.gap >= x[[3]][[xbar]] * 0.9) {
      x0<-rep(barcenter-arrow.cap, 2)
      x1<-rep(barcenter+arrow.cap, 2)
      y0<-rep(c(x[[1]][[xbar]]-x[[2]][[xbar]],x[[1]][[xbar]]+x[[3]][[xbar]]),2)
      y1<-rep(c(x[[1]][[xbar]]-x[[2]][[xbar]],x[[1]][[xbar]]+x[[3]][[xbar]]),2)
      segments(x0,y0,x1,y1)
     }
     else {
      x0<-x1<-rep(barcenter,2)
      y0<-c(x[[1]][[xbar]]+arrow.gap,x[[1]][[xbar]]-arrow.gap)
      y1<-c(x[[1]][[xbar]]+x[[3]][[xbar]],x[[1]][[xbar]]-x[[2]][[xbar]])
      arrows(x0,y0,x1,y1,length=caplen,angle=90)
     }
    }
   }
   if(showlabels) {
    par(xpd=TRUE)
    segments(c(start,start+barwidth,start),c(0,0,labely),
     c(start,start+barwidth,start+barwidth),rep(labely,3))
    boxed.labels(barcenter,labely,barlabels[xbar],
     bg=ifelse(is.na(col[xbar]),"white",col[xbar]),cex=labelcex)
    par(xpd=FALSE)
   }
   start<-start+barwidth+barspace
  }
 }
 else {
  ndim<-length(dimx)
  # assume start and end are the edges of the bar within which
  # the new bars must fit. First calculate the total space
  barspace<-(end-start)*shrink
  # then calculate the width of each bar
  barwidth<-((end-start)-barspace)/dimx[1]
  # calculate the space between bars and at the edges
  barspace<-barspace/(dimx[1]+1)
  sliceargs<-vector("list",ndim+1)
  xslice<-vector("list",4)
  start<-start+barspace
  for(slice in 1:dimx[1]) {
   for(stat in 1:3) {
    sliceargs[[1]]<-x[[stat]]
    sliceargs[[2]]<-slice
    for(arg in 3:(ndim+1)) sliceargs[[arg]]<-TRUE
    xslice[[stat]]<-do.call('[',sliceargs)
   }
   xslice[[4]]<-x[[4]]
   # send the sliced list as x to drawNestedBars
   drawNestedBars(xslice,start=start,end=start+barwidth,
    shrink=shrink,errbars=errbars,col=col,labelcex=labelcex,labely=labely,
    showbars=showbars,showlabels=showlabels,arrow.cap=arrow.cap)
   start<-start+barwidth+barspace
  }
 }
}