2015-09-02 10 views
17

Stosując ten manekin data.frameJak kontrolować kolejność skumulowany wykres słupkowy przy użyciu tożsamości na ggplot2

ts <- data.frame(x=1:3, y=c("blue", "white", "white"), z=c("one", "one", "two")) 

Staram i działka z kategorii „niebieski” na wierzchu.

ggplot(ts, aes(z, x, fill=factor(y, levels=c("blue","white")))) + geom_bar(stat = "identity") 

enter image description here

daje mi "białe" na wierzchu. i

ggplot(ts, aes(z, x, fill=factor(y, levels=c("white", "blue")))) + geom_bar(stat = "identity") 

enter image description here

odwraca kolory, ale wciąż daje mi "białe" na wierzchu. Jak mogę uzyskać "niebieski" na górze?

Odpowiedz

25

Już wcześniej walczyłem z tym samym problemem. Wygląda na to, że ggplot układa pręty w oparciu o ich wygląd w ramce danych. Tak więc rozwiązanie problemu jest sortowanie danych przez współczynnik wypełnienia w odwrotnej kolejności chcesz go do stawienia się w legendzie: dolny element na górze dataframe, a górna pozycja na dole:

ggplot(ts[order(ts$y, decreasing = T),], 
     aes(z, x, fill=factor(y, levels=c("blue","white")))) + 
    geom_bar(stat = "identity") 

enter image description here

Edycja: Więcej ilustracja

Korzystanie z przykładowych danych, stworzyłem trzy działki o różnych porządków w dataframe, myślałem, że więcej fill-zmienne by dokonać rzeczy nieco jaśniejsze.

set.seed(123) 
library(gridExtra) 
df <- data.frame(x=rep(c(1,2),each=5), 
       fill_var=rep(LETTERS[1:5], 2), 
       y=1) 
#original order 
p1 <- ggplot(df, aes(x=x,y=y,fill=fill_var))+ 
    geom_bar(stat="identity") + labs(title="Original dataframe") 


#random order 
p2 <- ggplot(df[sample(1:10),],aes(x=x,y=y,fill=fill_var))+ 
    geom_bar(stat="identity") + labs(title="Random order") 
#legend checks out, sequence wird 

#reverse order 
p3 <- ggplot(df[order(df$fill_var,decreasing=T),], 
      aes(x=x,y=y,fill=fill_var))+ 
    geom_bar(stat="identity") + labs(title="Reverse sort by fill") 

plots <- list(p1,p2,p3) 

do.call(grid.arrange,plots) 

enter image description here

+0

Dziękujemy za dokładny przykład! Myślałem, że kolejność została ustalona alfabetycznie, więc jest to bardzo pomocne. – Tom

+1

Nie ma za co! Jeśli któreś z dostarczonych rozwiązań działa zgodnie z oczekiwaniami, czy możesz je zaakceptować? Powoduje, że inni nie odpowiadają na pytanie. – Heroka

+1

Dobra odpowiedź! Być może inni uznają to pytanie za przydatne: http://stackoverflow.com/questions/30739602/ggplot-reorder-stacked-bar-plot-based-on-values-in-data-frame – lawyeR

6

Mam dokładnie ten sam problem dzisiaj. Można uzyskać blue na górze za pomocą order=-as.numeric():

ggplot(ts, 
aes(z, x, fill=factor(y, levels=c("blue","white")), order=-as.numeric(y))) + 
geom_bar(stat = "identity") 
+0

Dziwnie, to nie działa na moim komputerze. – Tom

+0

To też nie działa na moim. –

20

Na co warto, w wersji 2.2.1 ggplot2 kolejność stosu nie jest określona przez kolejność wierszy w data.frame. Zamiast tego dopasowuje kolejność legendy, określoną przez kolejność poziomów w współczynniku.

d <- data.frame(
    y=c(0.1, 0.2, 0.7), 
    cat = factor(c('No', 'Yes', 'NA'), levels = c('NA', 'Yes', 'No'))) 

# Original order 
p1 <- ggplot(d, aes(x=1, y=y, fill=cat)) + 
    geom_bar(stat='identity') 

# Change order of rows 
p2 <- ggplot(d[c(2, 3, 1), ], aes(x=1, y=y, fill=cat)) + 
    geom_bar(stat='identity') 

# Change order of levels 
d$cat2 <- relevel(d$cat, 'Yes') 
p3 <- ggplot(d, aes(x=1, y=y, fill=cat2)) + 
    geom_bar(stat='identity') 

grid.arrange(p1, p2, p3, ncol=3) 

Wynika to na poniższym wykresie: enter image description here

+0

Dziękujemy za wiadomość, że jest to spowodowane nową wersją ggplot2. W jakiś sposób moje spiski nagle wszystko się myliło i spędziłem dużo czasu na zlokalizowaniu błędu ze sobą. Dopiero teraz wiem, że problem polega na "ggplot2" i mogę bezpiecznie zmienić zamówienie ręcznie – Vincent

5

Użyj group aethetic w zaproszeniu ggplot(). Zapewnia to, że wszystkie warstwy są ułożone w stos w taki sam sposób.

series <- data.frame(
    time = c(rep(1, 4),rep(2, 4), rep(3, 4), rep(4, 4)), 
    type = rep(c('a', 'b', 'c', 'd'), 4), 
    value = rpois(16, 10) 
) 

ggplot(series, aes(time, value, group = type)) + 
    geom_col(aes(fill = type)) + 
    geom_text(aes(label = type), position = "stack") 
Powiązane problemy