简体   繁体   中英

How do I make stacked bar chart in specific order in ggplot/R while maintaining a specific color scheme?

I have a stacked bar chart with percentages explaining the reason someone left a bad review. Based on this SO answer , I have rigged my plot to be a single, stacked bar chart. However, I now want to order the bars based on the percentage of individuals who chosen that reason. If there's ties, it's okay whichever reason comes first, but the color scheme needs to stay consistent (ie, reason 1 must always be yellow).

I've tried reordering the dataset ( arrange(desc(percentage)) %>% ), but the results are the same. I've also seen other answers saying to order the x-axis, but my x axis variable is the same for everyone based on how I rigged the plot. Any help would be appreciated!

library(dplyr)
library(ggplot2)
library(scales)

#Test dataset
test_dataset <- tibble(reason = c("Reason 1", "Reason 2", "Reason 3", "Reason 4", "Reason 5"),
                       percentage = c(.10, .35, .25, .15, .15),
                       filler_variable = "filler_variable")

#specifying colors
colors <- c("red", "blue", "green", "orange", "yellow")

#Setting my variables in a set order to link them with their color
test_dataset$reason_factor <- factor(test_dataset$reason, levels= rev(c("Reason 1",
                                                                         "Reason 2",
                                                                         "Reason 3",
                                                                         "Reason 4",
                                                                        "Reason 5")))
#Making my plot
test_dataset %>%
  arrange(desc(percentage)) %>%
  ggplot(aes(x = filler_variable, y = percentage, fill = reason_factor)) + 
  geom_col(position="fill",width = 0.4) +
  coord_flip() +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1), limits = c(0, 1)) +
  scale_fill_manual(values = colors, guide = guide_legend(reverse = TRUE, nrow=2, byrow=TRUE))

One option would be to first use a named vector of colors which fixes the assignment of colors to categories. To order your bars by percentages you could reorder your reason_factor by percentage :

colors <- c("red", "blue", "green", "orange", "yellow")
names(colors) <- levels(test_dataset$reason_factor)

# Making my plot
ggplot(test_dataset, aes(y = filler_variable, x = percentage, fill = reorder(reason_factor, percentage))) +
  geom_col(position = "fill", width = 0.4) +
  scale_x_continuous(labels = scales::percent_format(accuracy = 1), limits = c(0, 1)) +
  scale_fill_manual(values = colors, guide = guide_legend(reverse = TRUE, nrow = 2, byrow = TRUE))

As an extension to Stefan's answer above, here is how you can get the legend to be rearranged as well:

#Run my original code to make dataset first

#Stefan's addition
colors <- c("red", "blue", "green", "orange", "yellow")
names(colors) <- levels(test_dataset$reason_factor)

#Makes a vector of the variables in the proper order
legend_order <- test_dataset %>%
  arrange(desc(percentage)) %>%
  dplyr::select(reason) %>%
  pull()

#Make the plot using Stefan's improvements, but now in scale_fill_manual (last line), add in a limits argument to set order of the key
test_dataset %>%
  arrange(desc(percentage)) %>%
  ggplot(aes(x = filler_variable, y = percentage, fill = reorder(reason_factor, percentage))) + 
  geom_col(position="fill",width = 0.4) +
  coord_flip() +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1), limits = c(0, 1)) +
  scale_fill_manual(values = colors, guide = guide_legend(nrow=2, byrow=TRUE), limits = legend_order)

在此处输入图像描述

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