2013-04-21 8 views
8

Obrazek poniżej pokazuje wykres, który utworzyłem za pomocą poniższego kodu. Podkreśliłem brakujące lub nakładające się etykiety. Czy istnieje sposób, aby powiedzieć, że ggplot2 nie nakłada się na etykiety?Jak zapobiec nakładaniu się dwóch etykiet w schemacie?

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

można drukować tekst o określonych współrzędnych. To nie jest najlepsze podejście, ale dostanie zadanie. –

+0

@Ricardo: To pomysł, ale pasek może być dowolnej wysokości. – Martin

Odpowiedz

10

Można użyć wariant znanego population pyramid.

Niektóre przykładowe dane (kod zainspirowany odpowiedź Didzis Elferts'): Ilość

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) 

Compute wyniki dla każdego tygodnia, a następnie przekształcić jedną kategorię do wartości ujemnych:

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

Narysuj wykres. Należy zauważyć, że znaczniki osi y są dostosowane do pokazywania dodatnich wartości po obu stronach linii podstawowej.

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))) 

Działka:

plot

do celów produkcyjnych trzeba by określić odpowiednie etykiety podziałki na osi Y dynamicznie.

5

Jedno rozwiązanie, aby uniknąć powielania działań jest wykorzystanie do pozycji Dodge barów i tekstów. Aby uniknąć brakujących wartości, możesz ustawić ylim. Oto przykład.

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

Wykonane nowe dane przykładowe (inspirowane przez kodeks @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) 

Korzystanie z biblioteki funkcji ddply()plyr wykonane nową ramkę danych text.df dla etykiet. Kolumna count zawiera liczbę obserwacji w każdej kombinacji Week i Status. Następnie dodano kolumnę ypos, która zawiera sumaryczną sumę count dla każdego tygodnia plus 15. To będzie używane dla pozycji y. Dla Not-Shippedypos zastąpiono przez -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 

Teraz etykiety są drukowane z geom_text() przy użyciu nowej ramki danych.

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

podstawie Didzis działce można również zwiększyć czytelność utrzymując pozycję na osi y przez stałą i kolorowania tekstu w tym samym kolorze co legendzie.

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

Powiązane problemy