【R】ggplot2绘图radical stacked bar chart

今天花一天时间画了一张图:先上成品

【R】ggplot2绘图radical stacked bar chart_第1张图片
Screen Shot 2017-02-24 at 8.09.25 PM.png

代码参考: http://stackoverflow.com/questions/24872193/circular-stacked-bar-plot-in-r
主要思路不变,分7个步骤,

Step0: perapare data

family item score time value
X1 Morris 1 0 x1.before 7.608795e-01
X2 Morris 2 0 x2.before 9.588929e-01
X11 Morris 1 1 x1.before 1.000000e+00
X21 Morris 2 1 x2.before 9.376825e-01
X12 Morris 3 0 x1.after 2.149399e-17
X22 Morris 4 0 x2.after 9.684344e-01
X13 Morris 3 1 x1.after 1.701453e-01
X23 Morris 4 1 x2.after 9.376825e-01
9 Sobol 5 2 x1.before 2.354235e-01
10 Sobol 6 2 x2.before -1.742957e-03
11 Sobol 5 3 x1.before 3.170810e-01
12 Sobol 6 3 x2.before 4.438829e-01
13 Sobol 7 2 x1.after 7.974484e-03
14 Sobol 8 2 x2.after 7.974484e-03
15 Sobol 7 3 x1.after 8.259899e-02
16 Sobol 8 3 x2.after 9.094265e-01
17 HSIC 9 4 x1.before 1.000000e+00
18 HSIC 10 4 x2.before 1.748387e-01
19 HSIC 11 4 x1.after 2.018042e-01
20 HSIC 12 4 x2.after 3.706424e-01

step1: 定义stacked bar chart,y从1开始到0, 重叠bar的顺序是先小bar再大bar
Step2.1: 定义白色刻度线位置,最大间隔由nguides决定
Step2.2: 定义刻度数值
Step3: 定义每个item的标签label,旋转角度由函数确定
Step4: 定义类标签(family),角度同样由旋转函数确定
Step5: 由二维坐标变为极坐标
Step6:通过scale_fill_brewer()定义legend和色带
Step7: 修改背景、坐标、legend等theme

全部代码如下:

binSize=1
spaceBar=0.05
spaceItem=0.2
spaceFamily=1.2
innerRadius=0.3
outerRadius=1
nguides=5##刻度的最大间隔数
alphaStart=-0.3
circleProportion=0.8
direction="inwards"
familyLabels=TRUE
itemSize=3
legLabels=NULL
legTitle="Source"
require(ggplot2)
require(plyr)
guides=pretty(range(c(0, df$value)), n=nguides, min.n=2)
# ordering
df<-arrange(df,family,item,score)

# family and item indices
df$indexFamily <- as.integer(factor(df$family))
df$indexItem <- with(df, as.integer(factor(item, levels=item[!duplicated(item)])))        
df$indexScore <- as.integer(factor(df$score))

df<-arrange(df,family,item,score)

# define the bins
M <- nlevels(factor(df$score))
vMax <- max(df$value)

guides <- guides[guides < vMax]
guides <- guides[guides >= 0]
#df$value <- df$value/vMax

# linear projection  
affine<-switch(direction,
               'inwards'= function(y) (outerRadius-innerRadius)*y+innerRadius,
               'outwards'=function(y) (outerRadius-innerRadius)*(1-y)+innerRadius,
               stop(paste("Unknown direction")))

###step1: 定义stacked bar chart,y从1开始到0, 重叠bar的顺序是先小bar再大bar
df<-within(df, {
  xmin <- (binSize + spaceBar) + 
    (indexItem - 1) * (spaceItem + (binSize + spaceBar)) +
    (indexFamily - 1) * (spaceFamily - spaceItem)
  xmax <- xmin + binSize
  ymax <- affine(1 - value)
}
)      
df<-df[with(df, order(family,item,value)), ]
#df<-ddply(df,.(item),mutate,ymin=(length(ymax)==1 ? 1 : c(1,ymax[1:(length(ymax)-1)])))
df<-ddply(df,.(item),mutate,ymin=c(1,ymax[-length(ymax)]))

###Step2.1: 定义白色刻度线位置
# build the guides
guidesDF<-data.frame(
  xmin=rep(df$xmin,length(guides)),
  y=rep(guides/vMax,1,each=nrow(df)))

guidesDF<-within(guidesDF,{
  xend<-xmin+binSize+spaceBar
  y<-affine(1-y)
})


# Building the ggplot object
totalLength<-tail(df$xmin+binSize+spaceBar+spaceFamily,1)/circleProportion-0

# histograms
p<-ggplot(df)+geom_rect(
  aes(
    xmin=xmin,
    xmax=xmax,
    ymin=ymin,
    ymax=ymax,
    fill=factor(score))
 # position = "identity"
)

# guides  
p<-p+geom_segment(
  aes(
    x=xmin,
    xend=xend,
    y=y,
    yend=y),
  colour="white",
  data=guidesDF)

###Step2.2: 定义刻度数值
# label for guides
guideLabels<-data.frame(
  x=0,
  y=affine(1-guides/vMax),
  label=guides
)

p<-p+geom_text(
  aes(x=x,y=y,label=label),
  data=guideLabels,
  angle=-alphaStart*180/pi,
  hjust=1,
  size=4)

# item labels
readableAngle<-function(x){
  angle<-x*(-360/totalLength)-alphaStart*180/pi+90
  angle+ifelse(sign(cos(angle*pi/180))+sign(sin(angle*pi/180))==-2,180,0)
}
readableJustification<-function(x){
  angle<-x*(-360/totalLength)-alphaStart*180/pi+90
  ifelse(sign(cos(angle*pi/180))+sign(sin(angle*pi/180))==-2,1,0)
}

###Step3: 定义每个item的标签label
dfItemLabels<-ddply(df,.(item),summarize,xmin=xmin[1])
dfItemLabels<-within(dfItemLabels,{
  #x <- xmin +  M * (binSize + spaceBar)/2
  x <- xmin+(binSize + spaceBar)/2
  #angle <- readableAngle(xmin +  M * (binSize + spaceBar)/2)
  #hjust <- readableJustification(xmin +  M * (binSize + spaceBar)/2)
  angle <- readableAngle(xmin +   (binSize + spaceBar)/2)
  hjust <- readableJustification(xmin +   (binSize + spaceBar)/2)
  item<-df$time[c(seq(1,(length(df$time)-4),2),c(17:20))]
})

p<-p+geom_text(
  size=4,
  aes(
    x=x,
    label=item,
    angle=angle,
    hjust=hjust),
  y=1.02,
  size=itemSize,
  vjust=0.5,
  data=dfItemLabels
  )

###Step4: 定义类标签(family)
# family labels
if(familyLabels){
  #     familyLabelsDF<-ddply(df,.(family),summarise,x=mean(xmin+binSize),angle=mean(xmin+binSize)*(-360/totalLength)-alphaStart*180/pi)
  familyLabelsDF<-aggregate(xmin~family,data=df,FUN=function(s) mean(s+binSize/2))
  familyLabelsDF<-within(familyLabelsDF,{
    x<-xmin
    angle<-xmin*(-360/totalLength)-alphaStart*180/pi
  })
  
  p<-p+geom_text(
    aes(
      x=x,
      label=family,
      angle=angle),
    data=familyLabelsDF,
    y=2,
    size=5)
}  

# x and y limits
p<-p+xlim(0,tail(df$xmin+binSize+spaceFamily,1)/circleProportion)
p<-p+ylim(0,outerRadius+0.7)

###Step5: 由二维坐标变为极坐标
# project to polar coordinates
p<-p+coord_polar(start=alphaStart)

###Step6:通过scale_fill_brewer()定义legend和色带
# nice colour scale
#if(is.null(legLabels)) legLabels <- levels(df$score)
#names(legLabels) <- levels(df$score)
if(is.null(legLabels)) legLabels <- c('sigma','mu.star','interaction','main','HSIC')
names(legLabels) <- levels(factor(df$score))
p<-p+scale_fill_brewer(name=legTitle, palette='Set1',type='qual', labels=legLabels)

###Step7: 修改背景、坐标、legend等theme
# empty background and remove guide lines, ticks and labels
p<-p+theme(
  #panel.background=theme_bw(),
  axis.title.x=element_blank(),
  axis.title.y=element_blank(),
  #panel.grid.major=element_blank(),
  #panel.grid.minor=element_blank(),
  axis.text.x=element_blank(),
  axis.text.y=element_blank(),
  axis.ticks=element_blank(),
  legend.text=element_text(size=10)
)
p

你可能感兴趣的:(【R】ggplot2绘图radical stacked bar chart)