0
votes

I have a df containing three columns:

-"sample" ~containing the sample names -"group" ~containing the group (first up, second up, remain up, remain down, second down, first down) -"value" ~containing the number in each group.

The samples I have ordered in my desired order in sorder, and applied as factor to order the ticks on the x-axis. In similar fashion I ordered the groups in gorder and applied them as factor to order stacks in the graph.

I am happy with the order of the groups (and their colors) in the legend, and would like the stacks to be ordered the same. I have tried re-ordering the factors, but short of picking the colors by hand I have not managed to get the stacks in the same order as the legend. Do you have any suggestions?

require(dplyr)
require(ggplot2)

gorder<-c("first up", "second up", "remain up", "remain down", "second down", "first down")

sorder<-c("55_NST", "40_NST","25_NST","ad_NST", "RH_NST", "FT_ST",  "55_ST", "25_ST")

set.seed(1)
df<-data.frame(
  "sample" =rep(sorder, each=6),
  "group"=rep(gorder, times=8),
  "value"=c(abs(rnorm(48,mean=3000, sd=500))))
df<-df%>%mutate(value =case_when(group %in% c("remain down", "second down", "first down") ~ value *(-1),
                                 !group %in% c("remain down", "second down", "first down") ~ value))


df$sample<-factor(df$sample, levels = sorder)
df$group<-factor(df$group, levels = gorder)

ggplot(df, aes(fill=group, y=value, x=sample)) + 
    geom_bar(position="stack", stat="identity") +
 theme_bw()+
  scale_x_discrete(breaks=sorder, labels=c("55", "40", "25", "AD", "RH", "FT (ST)", "55 (ST)", "25 (ST)"))+
  scale_y_continuous(breaks = seq(from = -12000,to = 12000, by = 2000))+
  labs(y="number of genes", x="RWC")+
  scale_fill_brewer(type = "div", palette = "RdYlGn",direction = -1)

Example graph, I would like the stacks in the same order as the legend colors

1
Could you please make your question reproducible by including a minimal dataset in the form of an object for example if a data frame as df <- data.frame(…) where … is your variables and values minimal reproducible examplePeter
Yes, of course, I put it in the editktm
You have an undefined variable in scale_x_discrete(breaks = sorder... where is sorder assigned? If it is a typo and should be gorder there still is a problem: Error: breaks` and labels must have the same length`. Have a look at this link for making a reproducible question: speakerdeck.com/jennybc/reprex-help-me-help-you?slide=5.Peter
Could you also use set.seed("a_number") to ensure consistent output?Peter
Alright, it should now definitely be reproduciblektm

1 Answers

0
votes

The difficulties seem to be the clash between using factors and the way ggplot handles negative values in position_stack.

From the documentation: "Stacking of positive and negative values are performed separately so that positive values stack upwards from the x-axis and negative values stack downward." It seems stacking trumps factors.

So a bit of manual intervention is needed:

1) re-order gorder to deal with stacking reversal of negative values

2) use scale_fill_manual and a reconstructed version of the colorBrewer palette to get the fill colours in the correct order in the chart. With labels in the required order.

3) override the legend guide so that the colours match with the original label order.

There may well be more efficient ways to achieve this...

library(ggplot2)
library(dplyr)
library(forcats)
library(RColorBrewer)

gorder<-c("first up", "second up", "remain up", "remain down", "second down", "first down")

gorder_col <- c("first up", "second up", "remain up", rev(c("remain down", "second down", "first down")))

sorder<-c("55_NST", "40_NST","25_NST","ad_NST", "RH_NST", "FT_ST",  "55_ST", "25_ST")

set.seed(1)

df<-data.frame(
  "sample" = rep(sorder, each=6),
  "group" = rep(gorder, times=8),
  "value" = c(abs(rnorm(48,mean=3000, sd=500))))

df<-
  df %>%
  mutate(value = case_when(group %in% c("remain down", "second down", "first down") ~ value * (-1),
                           !group %in% c("remain down", "second down", "first down") ~ value),
         sample = factor(sample, levels = sorder),
         group = factor(group, levels = gorder_col))


ggplot(df, aes(fill = group, y = value, x = sample)) + 
  geom_bar(position="stack", stat="identity") +
  theme_bw()+
  scale_x_discrete(breaks = sorder, labels = c("55", "40", "25", "AD", "RH", "FT (ST)", "55 (ST)", "25 (ST)"))+
  scale_y_continuous(breaks = seq(from = -12000,to = 12000, by = 2000))+
  labs(y="number of genes", x="RWC")+
  scale_fill_manual(values = c(brewer.pal(name = "RdYlGn", n = 6)[6:4], brewer.pal(name = "RdYlGn", n = 6)[1:3]),
                    labels = gorder)+
  guides(fill = guide_legend(override.aes = list(fill = brewer.pal(name = "RdYlGn", n = 6)[6:1])))