简体   繁体   中英

ggplot2 stacked bar not ordering by manually-defined factor order

I would like to manually define the order of the items in each stacked bar. From all of the research I've done, I should be able to do this by manually defining the order of these factors prior to plotting. For some reason I have not been successful.

Here is the raw data:

df <- structure(list(cross_valid = structure(c(1L, 2L, 1L, 2L, 1L, 
2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), .Label = c("1", 
"2"), class = "factor"), variable = structure(c(1L, 1L, 2L, 2L, 
3L, 3L, 4L, 4L, 5L, 5L, 6L, 6L, 7L, 7L, 8L, 8L, 9L, 9L), .Label = c("a", 
"b", "c", "d", "e", "f", "g", "h", "i"), class = "factor"), value = c(0, 
0, 0, 0, 3.546, 0, 0, 0, 28.0927688833, 4.689, 0.4887, 1.134, 
20.886690705, 16.8620595883, 14.8086, 18.648, 20.5713, 44.046
)), row.names = c(NA, -18L), class = "data.frame", .Names = c("cross_valid", 
"variable", "value"))

Looks like:

> head (df)
  cross_valid variable value
1           1        a 0.000
2           2        a 0.000
3           1        b 0.000
4           2        b 0.000
5           1        c 3.546
6           2        c 0.000

Current order and levels of df$variable :

> df$variable
 [1] a a b b c c d d e e f f g g h h i i
Levels: a b c d e f g h i

Now I change the order of df$variable :

df$variable <- factor(df$variable, levels = unique(c("i","a","b","e","g","f","h")),ordered=TRUE)

Now plot the graph:

library(ggplot2)
p <- ggplot() + geom_bar(data=df,aes(x=cross_valid,y=value,fill=variable),stat='identity')
p <- p + scale_fill_manual("",values=c('a'='darkred','b'='blue','c'='black','d'='darkolivegreen1','e'='green','f'='darkorchid','g'='yellow',
                                       'h'='snow4','i'='darkgray'),
                           breaks=c('i','h','g','f','e','d','c','b','a'),
                           labels=c('i','h','g','f','e','d','c','b','a'))
p

Which produces the following plot:

在此处输入图片说明

I defined 'i' and 'h' to be on opposite ends of the bar, yet they are still next to each other. Are there any ideas on why this might be happening? Maybe something is odd with my data?

Thanks

-al

EDIT 1:

Following @MrFlick's advice I removed breaks, but still find that 'i' and 'h' are still next to each other in the bar, even though the levels have defined them to be at opposite ends of the bar.

> df$variable
 [1] a a b b c c d d e e f f g g h h i i
Levels: i < a < b < c < d < e < g < f < h

Edited plot code:

p <- ggplot() + geom_bar(data=df,aes(x=cross_valid,y=value,fill=variable),stat='identity')
p <- p + scale_fill_manual("",values=c('a'='darkred','b'='blue','c'='black','d'='darkolivegreen1','e'='green','f'='darkorchid','g'='yellow',
                                       'h'='snow4','i'='darkgray'))
p

Produces:

在此处输入图片说明

Following works for me:

df$variable <- relevel(df$variable, "i")

library(ggplot2)
p <- ggplot() + 
  geom_bar(data=df,aes(x=cross_valid,y=value,fill=variable,order=variable),stat='identity') +
  scale_fill_manual("",
                    values=c('a'='darkred','b'='blue','c'='black','d'='darkolivegreen1','e'='green','f'='darkorchid','g'='yellow','h'='snow4','i'='darkgray'),
                    breaks=c('h','g','f','e','d','c','b','a','i'),
                    labels=c('h','g','f','e','d','c','b','a','i'))
p

I used relevel to change factor level order and added an order parameter to the aes . Edit: Changing the order of breaks and labels also adjusts the legend accordingly.

在此处输入图片说明

Second Edit: Sorry, solution was already posted in comments above, didn't see that before answering...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM