Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Stacked barplot with colors depending on numbers and length of a vector

I have a dataframe that looks like this

df <- data.frame("V1" = c(0,0,0,0,0,2,2,2,2,2),
                 "V2" = c(9,9,9,0,0,2,2,2,0,0))

I would like to create a stacked barplot in this fashion:
enter image description here

So basically I map a certain value to a corresponding color (9 -> white (invisible), 0 -> green 2 -> red), and then create a bar of a length that is equal to the number of appearances of the value in a dataframe column. Is there any way to do something like this, i.e. using ggplot2?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You could change your dataframe to a long format using pivot_longer. Add a column with the colors you want to show the bars using case_when for example. You could use scale_fill_identity to fill the bars to the corresponding color. To get the same order fill in your stacked bars as your dataframe, you could use ggplot_build to modify the data of your plot by replace the column of "fill" with a vector of the same order as your dataframe. You can use the following code:

library(ggplot2)
library(tidyr)
library(dplyr)
library(scales)
# Create plot
p <- df %>%
  mutate(index = 1) %>%
  pivot_longer(cols = -index) %>%
  mutate(color = case_when(value == 9 ~ 'white',
                           value == 0 ~ 'darkgreen',
                           TRUE ~ 'red')) %>%
  ggplot(aes(x = index, y = name, fill = color)) +
  geom_col(width = 0.3) +
  scale_fill_identity() +
  theme_classic() +
  scale_x_continuous(expand = c(0,0), breaks = pretty_breaks(2)) +
  labs(x = '', y = '')

# Extract vector of colors in right order
vec_colors <- df %>%
  mutate(index = 1) %>%
  pivot_longer(cols = -index) %>%
  mutate(color = case_when(value == 9 ~ 'white',
                           value == 0 ~ 'darkgreen',
                           TRUE ~ 'red')) %>%
  arrange(name) %>%
  pull(color)

# right order colors
vec_colors
#>  [1] "darkgreen" "darkgreen" "darkgreen" "darkgreen" "darkgreen" "red"      
#>  [7] "red"       "red"       "red"       "red"       "white"     "white"    
#> [13] "white"     "darkgreen" "darkgreen" "red"       "red"       "red"      
#> [19] "darkgreen" "darkgreen"

# use ggplot_build to modify data and replace fill column with vector
q <- ggplot_build(p)
q$data[[1]] <- q$data[[1]] %>%
  group_by(y) %>%
  arrange(x, .by_group = TRUE) 

q$data[[1]]$fill <- vec_colors

q <- ggplot_gtable(q)

# plot 
plot(q)

Created on 2022-09-17 with reprex v2.0.2

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading