2017-06-06 10 views
1

Ich versuche, eine divergierende gestapelte Bar wie here zu erstellen, und habe ein ähnliches Problem zu dieser SO question. Meine Herangehensweise ist jedoch etwas anders, da ich alles über einen einzigen Datensatz statt über zwei verwalte und meine Farben unabhängig von meinen Daten sind.ggplot seltsame Reihenfolge der gestapelten Bar

Reprex wie folgt:

library(tidyverse) 
library(RColorBrewer) 
x <- tribble(
    ~response, ~count, 
    0,   -27, 
    1,   -9, 
    2,   -41, 
    3,   -43, 
    4,   -58, 
    5,  -120, 
    5,   120, 
    6,   233, 
    7,   379, 
    8,   388, 
    9,   145, 
    10,   61 
) %>% 
    mutate(response = factor(response)) 

ggplot(x, aes(x = 1, y = count, fill = response)) + 
    geom_col() + 
    scale_fill_brewer(palette = "RdBu") + 
    coord_flip() 

Das gibt mir ein Bild wie folgt aus: enter image description here

Das Problem ist mit der Bestellung der gestapelten Daten auf der rechten Seite des Null zu tun, wo sie Stapeln scheint in absteigender Reihenfolge zu sein. Irgendwelche Gedanken darüber, wie dieses Problem beheben würde sehr geschätzt werden (erwartete Bestellung 0-10 wäre, nicht 0-5,10-5)

Antwort

1

eine schwierige Frage! Ich spielte mit der Bestellung und es scheint, dass geom_bar und geom_col es nicht mögen, wenn Sie positive und negative Werte in der gleichen Reihenfolge kombinieren. So teilte ich Ihre Daten innerhalb des Datenrahmen für positive und negative Werte, erzeugen Farben für jeden Antwortwert und verwenden zwei GEOMS für positive und negative Werte getrennt:

library(tidyverse) 
library(RColorBrewer) 
x <- tribble(
    ~response, ~count, 
    0,   -27, 
    1,   -9, 
    2,   -41, 
    3,   -43, 
    4,   -58, 
    5,  -120, 
    5,   120, 
    6,   233, 
    7,   379, 
    8,   388, 
    9,   145, 
    10,   61 
) %>% 
    # Get absolute values and add dummy to distuingish positive and negative values 
    mutate(subzero = count < 0, 
     count = abs(count)) 

# Generate variable with colors from ColorBrewer for every response level (ugly but works) 
colors <- brewer.pal(length(unique(x$response)),"RdBu") 
x$colors <- NA 
for (i in 1:nrow(x)){ 
    x$colors[i] <- colors[x$response[i]+1] 
} 


ggplot() + 
    geom_bar(data = x[x$subzero==T,], aes(x = "", y = -count, fill = reorder(colors, response)), position="stack", stat="identity") + 
    geom_bar(data = x[x$subzero==F,], aes(x = "", y = count, fill = reorder(colors, -response)), position="stack", stat="identity") + 
    geom_hline(yintercept = 0, color =c("black")) + 
    scale_fill_identity("Response", labels = unique(x$response), breaks=unique(x$colors), guide="legend") + 
    coord_flip() + 
    labs(y="",x="") + 
    theme(legend.position = "bottom", legend.direction = "horizontal") + 
    scale_y_continuous(breaks=seq(-1400,1400,200), limits=c(-1400,1400)) 

UPD: aus Y-Skala ausgeglichen, so dass es mehr klar sehen enter image description here

1

Obwohl nicht intuitiv (für mich), zu verwenden:

ggplot(x, aes(x = 1, y = order(count), fill = response)) + 
    geom_col() + 
    scale_fill_brewer(palette = "RdBu",direction=1) + 
    coord_flip() 

es berücksichtigt die Reihenfolge basierend auf Antwort (und nicht um (Antwort))

+0

Es ist ein kniffliger, denn letztlich sollte das ähnlich einer Likert-Skala sein, die 0:10, von links nach rechts, anordnet. Der Grund dafür, dass es 2 Datensätze für 5 gibt, liegt darin, dass ich die Hälfte auf beiden Seiten des "Mittelpunkts" des Diagramms haben möchte. Diese Bestellung entspricht nicht ganz dem Zweck. – Dan

+0

Ah ja, es ist, bemerkte nachher die Reihenfolge ist umgekehrt (relativ zur Legende). Außerdem stellen die Werte die geordneten Werte dar (nicht die tatsächlichen Zählungen), was dies zu einer suboptimalen Antwort macht :) Alternativ können Sie die Variablen nach Anzahl sortieren, eine manuelle Skala einschließlich 'RColorBrewer :: brewer.pal (11," RdBu ") erstellen '(Wiederholen Sie 5) und fügen Sie es Ihrem df. Dies kann als Eingabe für 'scale_fill_manual' verwendet werden. – timfaber

0

können Sie verwenden position_stack(reverse=TRUE):

ggplot(x, aes(x = 1, y = count, fill = response)) + 
    geom_col(position = position_stack(reverse=TRUE)) + 
    scale_fill_brewer(palette = "RdBu") + 
    coord_flip() 
+0

Funktioniert immer noch nicht, da das Rot in der Mitte statt in Blau endet. – Dan

Verwandte Themen