Home > Software design >  R code - help creating a 100% stacked bar chart like the below image with ggplot:
R code - help creating a 100% stacked bar chart like the below image with ggplot:

Time:09-11

I have the below dataframe reproducible code:

dput(u) <-
structure(list(name = c("rankings_message_1", "rankings_message_2", 
"rankings_message_3", "rankings_message_4", "rankings_message_5", 
"rankings_message_6", "rankings_message_7", "rankings_message_8", 
"rankings_message_9", "rankings_message_10", "rankings_message_11", 
"rankings_message_12", "rankings_message_13", "rankings_message_1", 
"rankings_message_2", "rankings_message_3", "rankings_message_4", 
"rankings_message_5", "rankings_message_6", "rankings_message_7", 
"rankings_message_8", "rankings_message_9", "rankings_message_10", 
"rankings_message_11", "rankings_message_12", "rankings_message_13", 
"rankings_message_1", "rankings_message_2", "rankings_message_3", 
"rankings_message_4", "rankings_message_5", "rankings_message_6", 
"rankings_message_7", "rankings_message_8", "rankings_message_9", 
"rankings_message_10", "rankings_message_11", "rankings_message_12", 
"rankings_message_13", "rankings_message_1", "rankings_message_2", 
"rankings_message_3", "rankings_message_4", "rankings_message_5", 
"rankings_message_6", "rankings_message_7", "rankings_message_8", 
"rankings_message_9", "rankings_message_10", "rankings_message_11", 
"rankings_message_12", "rankings_message_13", "rankings_message_1", 
"rankings_message_2", "rankings_message_3", "rankings_message_4", 
"rankings_message_5", "rankings_message_6", "rankings_message_7", 
"rankings_message_8", "rankings_message_9", "rankings_message_10", 
"rankings_message_11", "rankings_message_12", "rankings_message_13", 
"rankings_message_1", "rankings_message_2", "rankings_message_3", 
"rankings_message_4", "rankings_message_5", "rankings_message_6", 
"rankings_message_7", "rankings_message_8", "rankings_message_9", 
"rankings_message_10", "rankings_message_11", "rankings_message_12", 
"rankings_message_13", "rankings_message_1", "rankings_message_2", 
"rankings_message_3", "rankings_message_4", "rankings_message_5", 
"rankings_message_6", "rankings_message_7", "rankings_message_8", 
"rankings_message_9", "rankings_message_10", "rankings_message_11", 
"rankings_message_12", "rankings_message_13", "rankings_message_1", 
"rankings_message_2", "rankings_message_3", "rankings_message_4", 
"rankings_message_5", "rankings_message_6", "rankings_message_7", 
"rankings_message_8", "rankings_message_9", "rankings_message_10", 
"rankings_message_11", "rankings_message_12", "rankings_message_13", 
"rankings_message_1", "rankings_message_2", "rankings_message_3", 
"rankings_message_4", "rankings_message_5", "rankings_message_6", 
"rankings_message_7", "rankings_message_8", "rankings_message_9", 
"rankings_message_10", "rankings_message_11", "rankings_message_12", 
"rankings_message_13", "rankings_message_1", "rankings_message_2", 
"rankings_message_3", "rankings_message_4", "rankings_message_5", 
"rankings_message_6", "rankings_message_7", "rankings_message_8", 
"rankings_message_9", "rankings_message_10", "rankings_message_11", 
"rankings_message_12", "rankings_message_13", "rankings_message_1", 
"rankings_message_2", "rankings_message_3", "rankings_message_4", 
"rankings_message_5", "rankings_message_6", "rankings_message_7", 
"rankings_message_8", "rankings_message_9", "rankings_message_10", 
"rankings_message_11", "rankings_message_12", "rankings_message_13", 
"rankings_message_1", "rankings_message_2", "rankings_message_3", 
"rankings_message_4", "rankings_message_5", "rankings_message_6", 
"rankings_message_7", "rankings_message_8", "rankings_message_9", 
"rankings_message_10", "rankings_message_11", "rankings_message_12", 
"rankings_message_13", "rankings_message_1", "rankings_message_2", 
"rankings_message_3", "rankings_message_4", "rankings_message_5", 
"rankings_message_6", "rankings_message_7", "rankings_message_8", 
"rankings_message_9", "rankings_message_10", "rankings_message_11", 
"rankings_message_12", "rankings_message_13"), value = c(5, 6, 
3, 13, 10, 12, 7, 19, 3, 7, 3, 5, 6, 6, 3, 6, 13, 7, 15, 9, 11, 
7, 6, 6, 4, 8, 7, 8, 4, 11, 6, 11, 11, 11, 6, 6, 5, 8, 6, 8, 
7, 6, 9, 6, 11, 9, 7, 9, 7, 7, 7, 6, 8, 6, 8, 7, 9, 7, 7, 10, 
9, 6, 7, 9, 7, 7, 11, 7, 7, 8, 7, 6, 7, 9, 10, 7, 8, 7, 8, 7, 
11, 5, 6, 4, 7, 4, 11, 9, 6, 10, 11, 9, 8, 9, 5, 7, 6, 6, 6, 
8, 9, 9, 8, 10, 9, 9, 9, 5, 5, 4, 7, 6, 9, 11, 10, 9, 8, 10, 
7, 10, 6, 4, 6, 7, 5, 7, 8, 8, 10, 10, 8, 7, 8, 7, 6, 7, 7, 4, 
9, 8, 11, 8, 9, 9, 8, 9, 9, 7, 4, 7, 5, 8, 9, 10, 7, 6, 5, 13, 
10, 4, 18, 5, 11, 4, 4, 5, 9, 6, 5)), row.names = c(NA, -169L
), class = c("tbl_df", "tbl", "data.frame"))

And this is my ggplot code:

ggplot(u, aes(value, factor(value), fill = name))  
  geom_bar(stat = "identity", position = "fill")  # #position fill makes them all 100%
  geom_text(aes(label=value), position = position_stack(vjust = .5), color = "White", size =7)

which makes this chart:

enter image description here

But I want to create something like this:

enter image description here

Ive tried different combinations inside ggplot but cant seem to get it to show right. I believe I need to use the factor functior in there somewhere but could be mistaken.... Overall, each bar is a "message" and each message/bar is broken down into 13 chunks which are %'s. I want each % chunck to be a different color as shown in the image I am trying to create. Any help would be appreciated!

CodePudding user response:

Your data contains the y axis variable ("name") and the x axis variable ("value"), but does not contain a grouping variable by which to stack or color-fill the bars (the original has a variable called "rank" which you don't have).

You can make an equivalent variable by grouping by the "name" variable and creating a sequence along the group which you then convert to a factor. You need to use position = "fill" on the text as well as the bars.

library(tidyverse)

u %>%
  group_by(name) %>%
  mutate(element = factor(row_number(name))) %>%
  ggplot(aes(value, name, fill = element))  
  geom_col(position = "fill")  
  geom_text(aes(label=value), position = position_fill(vjust = .5), 
            color = "White", size = 7)  
  scale_fill_discrete(guide = "none")

enter image description here

Or, to get it to look more like the original, use facets, a dummy y variable, an appropriate color palette and some theme changes:

u %>%
  group_by(name) %>%
  mutate(element = factor(row_number(name)),
         name = factor(name,
                       paste("rankings_message", 13:1, sep = "_"))) %>%
  
  ggplot(aes(value, "1", fill = element))  
  geom_col(position = "fill", orientation = "y", size = 0.5, col = "white")  
  geom_text(aes(label=value), position = position_fill(vjust = .5), 
            color = "White", size = 7)  
  scale_fill_manual(guide = "none",
                    values = rev(c("#ffb04d", "#ff8a1e", "#e5573e", "#af0020",
                                   "#3e84ac", "#64baff", "#96a7dd", "#765ab1", 
                                   "#483374", "#ce74a5", "#ffb04d", "#ff8a1e",
                                   "#e3583f")))  
  facet_wrap(vars(name), nrow = 13)  
  theme_void()  
  theme(strip.text = element_text(hjust = 0.05))

enter image description here

  • Related