Jenny
Jenny

Reputation: 69

How to reorder categories on ggplot2 axis

I am trying to reorder categories on my ggplot2 axis so that they are in the order Dark, Medium, Light instead of in alphabetical order.

I have tried to reorder them, and the bars show the correct orders, but the labels of Medium and Light have not switched to reflect the correct order.

Here is some reproducible code:

df = data.frame(Group = c(rep('A',6), rep('B',6), rep('C',6)),
               Status = c('0', '0', '0', '1', '1', '1', '0', '0', '0', '1', '1', '1','0', '0', '0', '1', '1', '1'),
               Color = c('Dark','Light','Medium','Dark','Light','Medium','Dark','Light','Medium','Dark','Light','Medium','Dark','Light','Medium','Dark','Light','Medium'),
               Count = c(3,6,9,3,4,1,5,2,7,3,4,8,5,3,7,6,2,6))

df <- df %>% group_by(Group, Status) %>% dplyr::mutate(percent = round(Count*100/sum(Count), 1))


ggplot(data = df, aes(x = Color, fill = Group, alpha= Status)) +
 scale_alpha_manual(values = c(1, 0.5)) +
 geom_bar(data=df[df$Status=="1",], aes(y=percent), stat="identity") +
 geom_bar(data=df[df$Status=="0",], aes(y=-percent), stat="identity") +
 scale_x_discrete(labels = df$Color) +
 coord_flip(ylim=c(-80,80)) +
 theme(text = element_text(size=16)) +
 scale_y_continuous(breaks=seq(-80,80,20),labels=abs(seq(-80,80,20))) + 
 scale_fill_brewer(palette="Set2") +
 facet_wrap(~Group, ncol=1) + theme(legend.position="right") +
 labs(y="Percentage", x="Colour", fill="Group", alpha = "Status") +
 theme_light()

Here is the Plot produced:

Plot

I've tried to reorder the categories using a couple methods such as adding limits

scale_x_discrete(labels = df$Color, limits = c("Dark", "Medium", "Light"))

and creating another column with reordered categories.

df$Color2 <- factor(df$Color, level = c('Dark', 'Medium', 'Light'))

What I am getting is plots represented the way I want them to be leveled, but with the labels Medium and Light as is instead of being switched:

Plot with inaccurate labels

How can I reorder my categories and get the labels to represent what they should represent?

Upvotes: 1

Views: 1472

Answers (1)

Adam Quek
Adam Quek

Reputation: 7153

df$Color contains a vector of Dark, Light, Medium, Dark, Light, Medium,.... And since there's only 3 labels, it take the first 3 values. Would work if you put in scale_x_discrete(labels = levels(df$Color)). But it's superfluous at this point.

df$Color <- factor(df$Color, levels=c("Light", "Medium", "Dark"))

ggplot(data = df, aes(x = Color, fill = Group, alpha= Status)) +
  scale_alpha_manual(values = c(1, 0.5)) +
  geom_bar(data=df[df$Status=="1",], aes(y=percent), stat="identity") +
  geom_bar(data=df[df$Status=="0",], aes(y=-percent), stat="identity") +
  #scale_x_discrete(labels = df$Color) +
  coord_flip(ylim=c(-80,80)) +
  theme(text = element_text(size=16)) +
  scale_y_continuous(breaks=seq(-80,80,20),labels=abs(seq(-80,80,20))) + 
  scale_fill_brewer(palette="Set2") +
  facet_wrap(~Group, ncol=1) + theme(legend.position="right") +
  labs(y="Percentage", x="Colour", fill="Group", alpha = "Status") +
  theme_light()

enter image description here

Upvotes: 2

Related Questions