web-dev-qa-db-fra.com

Comment contrôler l'ordre du graphique à barres empilées en utilisant identity sur ggplot2

Utiliser ce mannequin data.frame

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

J'essaie de tracer avec la catégorie "bleu" sur le dessus.

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

enter image description here

me donne "blanc" sur le dessus. et

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

enter image description here

inverse les couleurs, mais me donne toujours "blanc" sur le dessus. Comment puis-je obtenir "bleu" sur le dessus?

30
Tom

J'ai déjà eu du mal avec le même problème. Il semble que ggplot empile les barres en fonction de leur apparence dans le cadre de données. La solution à votre problème consiste donc à trier vos données en fonction du facteur de remplissage, dans l'ordre inverse de celui dans lequel vous souhaitez qu'elles apparaissent dans la légende: élément inférieur en haut du cadre de données et élément supérieur en bas:

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

Edit: Plus d'illustration

En utilisant des exemples de données, j'ai créé trois tracés avec différents ordres du cadre de données. Je pensais que plus de variables de remplissage rendraient les choses un peu plus claires.

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

44
Heroka

Pour ce que cela vaut, dans ggplot2 version 2.2.1, l’ordre de la pile n’est plus déterminé par l’ordre des lignes dans le fichier data.frame. Au lieu de cela, il correspond à l'ordre de la légende, déterminé par l'ordre des niveaux dans le facteur.

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)

Il en résulte le tracé ci-dessous: enter image description here

42
Inhabitant

Utilisez la méthode group dans l'appel ggplot(). Cela garantit que toutes les couches sont empilées de la même manière.

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")
6
Anne

J'ai exactement le même problème aujourd'hui. Vous pouvez obtenir blue par dessus en utilisant order=-as.numeric():

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

J'ai eu un problème similaire et je me suis déplacé en modifiant le niveau du facteur. pensais partager le code:

library(reshape2)
library(ggplot2)

group <- c(
  "1",
  "2-4",
  "5-9",
  "10-14",
  "15-19",
  "20-24",
  "25-29",
  "30-34",
  "35-39",
  "40-44",
  "45-49"
)

xx <- factor(group, levels(factor(group))[c(1, 4, 11, 2, 3, 5:10)])

method.1 <- c(36, 14, 8, 8, 18, 1, 46, 30, 62, 34, 34)
method.2 <- c(21, 37, 45, 42, 68, 41, 16, 81, 51, 62, 14)
method.3 <- c(37, 46, 18, 9, 16, 79, 46, 45, 70, 42, 28)  
elisa.neg <- c(12, 17, 18, 6, 19, 14, 13, 13, 7, 4, 1)  
elisa.eq <- c(3, 6, 3, 14, 1, 4, 11, 13, 5, 3, 2)

test  <- data.frame(person = xx, 
                    "Mixture Model" = method.1,
                    "Censoring" = method.3,
                    "ELISA neg" = elisa.neg,
                    "ELISA eqiv" = elisa.eq) 

melted <- melt(test, "person")
melted$cat <- ifelse(melted$variable == "Mixture.Model", "1",
                     ifelse(melted$variable == "Censoring", "2", "3"))

melted$variable = factor(melted$variable, levels = levels(melted$variable)[c(1, 2, 4,3 )]) ## This did the trick of changing the order

ggplot(melted, aes(x = cat, y = value, fill = variable)) + 
  geom_bar(stat = 'identity') + facet_wrap(~ person) +
  theme(axis.ticks.x=element_blank(),
        axis.text.x=element_blank()) + 
  labs(title = "My Title",
       y = "Per cent", x = "Age Group", fill = "")

(Désolé, ce sont mes données, je n'ai pas reproduit en utilisant les données de la publication originale, espérons que ça va!)

1
Kevin Wang