2013-04-21 56 views
8

下圖顯示了我用下面的代碼創建的圖表。我強調了缺失或重疊的標籤。有沒有辦法告訴ggplot2不重疊標籤?如何防止兩個標籤在條形圖中重疊?

enter image description here

week = c(0, 1, 1, 1, 1, 2, 2, 3, 4, 5) 
statuses = c('Shipped', 'Shipped', 'Shipped', 'Shipped', 'Not-Shipped', 'Shipped', 'Shipped', 'Shipped', 'Not-Shipped', 'Shipped') 

dat <- data.frame(Week = week, Status = statuses) 

p <- qplot(factor(Week), data = dat, geom = "bar", fill = factor(Status)) 
p <- p + geom_bar() 
# Below is the most important line, that's the one which displays the value 
p <- p + stat_bin(aes(label = ..count..), geom = "text", vjust = -1, size = 3) 
p 
+0

您可以在特定座標處繪製文本。這不是最好的方法,但它會完成工作。 – 2013-04-21 02:47:52

+0

@Ricardo:這是一個想法,但酒吧可以是任何高度。 – Martin 2013-04-22 14:58:11

回答

10

可以使用知名population pyramid的變體。

一些樣本數據(代碼由Didzis Elferts的回答啓發):

set.seed(654) 
week <- sample(0:9, 3000, rep=TRUE, prob = rchisq(10, df = 3)) 
status <- factor(rbinom(3000, 1, 0.15), labels = c("Shipped", "Not-Shipped")) 
data.df <- data.frame(Week = week, Status = status) 

計算算分數,每星期,然後一類轉換爲負值:

library("plyr") 
plot.df <- ddply(data.df, .(Week, Status), nrow) 
plot.df$V1 <- ifelse(plot.df$Status == "Shipped", 
        plot.df$V1, -plot.df$V1) 

繪製曲線。請注意,y軸標籤適合在基線的任一側顯示正值。

library("ggplot2") 
ggplot(plot.df) + 
    aes(x = as.factor(Week), y = V1, fill = Status) + 
    geom_bar(stat = "identity", position = "identity") + 
    scale_y_continuous(breaks = 100 *  -1:5, 
        labels = 100 * c(1, 0:5)) + 
    geom_text(aes(y = sign(V1) * max(V1)/30, label = abs(V1))) 

情節:

plot

對於你需要動態地確定合適的y軸刻度標籤生產的目的。

5

一種解決方案,以避免重疊是用來酒吧和文本躲閃位置。爲避免缺失值,您可以設置ylim。這裏是一個例子。

enter image description here

## I create some more realistic data similar to your picture 
week <- sample(0:5,1000,rep=TRUE) 
statuses <- gl(2,1000,labels=c('Not-Shipped', 'Shipped')) 
dat <- data.frame(Week = week, Status = statuses) 

## for dodging 
dodgewidth <- position_dodge(width=0.9) 
## get max y to set ylim 
ymax <- max(table(dat$Week,dat$Status))+20 
ggplot(dat,aes(x = factor(Week),fill = factor(Status))) + 
    geom_bar(position = dodgewidth) + 
    stat_bin(geom="text", position= dodgewidth, aes(label=..count..), 
      vjust=-1,size=5)+ 
    ylim(0,ymax) 
7

製造新的樣本數據(由@agstudy的代碼啓發)。

week <- sample(0:5,1000,rep=TRUE,prob=c(0.2,0.05,0.15,0.5,0.03,0.1)) 
statuses <- gl(2,1000,labels=c('Not-Shipped', 'Shipped')) 
dat <- data.frame(Week = week, Status = statuses) 

從庫plyr使用功能ddply()取得了新的數據幀text.df的標籤。列count包含每個組合WeekStatus中的觀察值的數目。然後添加列ypos,其中包含每週加累計數count加15。這將用於y位置。用Not-Shippedypos替換爲-10。

library(plyr) 
text.df<-ddply(dat,.(Week,Status),function(x) data.frame(count=nrow(x))) 
text.df<-ddply(text.df,.(Week),transform,ypos=cumsum(count)+15) 
text.df$ypos[text.df$Status=="Not-Shipped"]<- -10 

現在使用新的數據框標記geom_text()

ggplot(dat,aes(as.factor(Week),fill=Status))+geom_bar()+ 
    geom_text(data=text.df,aes(x=as.factor(Week),y=ypos,label=count)) 

enter image description here

3

基於Didzis情節,你也可以通過保持在y軸上固定的位置,並通過着色相同顏色的圖例中的文本增加可讀性。

library(ggplot2) 
week <- sample(0:5,1000,rep=TRUE,prob=c(0.2,0.05,0.15,0.5,0.03,0.1)) 
statuses <- gl(2,1000,labels=c('Not-Shipped', 'Shipped')) 
dat <- data.frame(Week = week, Status = statuses) 


library(plyr) 
text.df<-ddply(dat,.(Week,Status),function(x) data.frame(count=nrow(x))) 
text.df$ypos[text.df$Status=="Not-Shipped"]<- -15 
text.df$ypos[text.df$Status=="Shipped"]<- -55 

p <- ggplot(dat,aes(as.factor(Week),fill=Status))+geom_bar()+ 
geom_text(data=text.df,aes(x=as.factor(Week),y=ypos,label=count),colour=ifelse(text.df$Status=="Not-Shipped","#F8766D","#00BFC4")) 

enter image description here