Home > Blockchain >  bar chart in ggplot
bar chart in ggplot

Time:10-10

I have the following data: enter image description here

I want to have a bar chart where for each group I have two bars (IT and PT) side by side: this is my script:

 ggplot(score, aes(group, IT, fill = stain))  
    geom_bar(stat="identity", position = "fill")   
      scale_y_continuous(labels = scales::percent_format())  
    ggplot(score, aes(group, PT, fill = stain))  
     geom_bar(stat="identity", position = "fill") 
    scale_fill_manual(values = c("#edae49", "#d1495b", "#00798c", "#30638e")) 
      scale_y_continuous(labels = scales::percent_format())   
     ggtitle("CD4") 

how can I put the PT and IT on the same y-axis. Also how can I keep 0% values on the plot without having the auto NA instead?

CodePudding user response:

It will make life easier if you start by pivoting your data into long format. That is, instead of having one column for IT and one for PT, you have a single column with all the values, and another column labeling the value in that row as coming from either PT or IT. You can do this easily with pivot_longer.

It sounds like you want to stack the bars according to group, but have them dodged according to IT / PT. You can't both stack and dodge directly, but you can fake it with facets:

Your code might then look something like this:

library(tidyverse)

score %>%
  pivot_longer(IT:PT, names_to = 'IT_PT') %>%
  mutate(stain = factor(stain, unique(stain)),
         group = factor(group, unique(group))) %>%
  ggplot(aes(IT_PT, value, fill = group))  
  geom_col(position = 'fill')  
  theme_minimal(base_size = 16)  
  facet_grid(.~stain, switch = 'x')  
  scale_fill_manual(name = NULL, values =  c("#edae49", "#d1495b", 
                                             "#00798c", "#30638e"))  
  scale_x_discrete(labels = c('', ''), name = 'Stain', 
                   expand = c(0.1, 0.7))  
  scale_y_continuous(labels = scales::percent_format())   
  theme(panel.spacing.x = unit(0, 'mm'))

enter image description here


Data used

Obviously, I don't have your data, so I had to transcribe it manually from the picture in your question.

score <- structure(list(group = c("All_BrM", "All_BrM", "All_BrM", "All_BrM", 
"Sync", "Sync", "Sync", "Sync", "Meta", "Meta", "Meta", "Meta", 
"Poly", "Poly", "Poly", "Poly"), stain = c("0%", "<10%", "11-40%", 
">40%", "0%", "<10%", "11-40%", ">40%", "0%", "<10%", "11-40%", 
">40%", "0%", "<10%", "11-40%", ">40%"), IT = c(20, 35, 1, 0, 
2, 13, 1, 0, 9, 9, 0, 0, 9, 13, 0, 0), PT = c(9, 30, 6, 0, 1, 
9, 1, 0, 4, 10, 2, 0, 4, 11, 3, 0)), class = "data.frame", 
row.names = c(NA, -16L))

CodePudding user response:

@Allan Cameron

score$group <- factor(score$group, levels=c("All_BrM", "Sync","Meta","Poly" ))
  score$stain <- factor(score$stain, levels=c("none", "<10%","10-40%",">40%" ))
  
  ggplot(score, aes(group, IT, fill = stain))  
    geom_bar(stat="identity", position = "fill")   
      scale_fill_manual(values = c("#ded9e2", "#c0b9dd", "#80a1d4", "#75c9c8")) 
      theme_prism(base_size = 9) 
      scale_y_continuous(labels = scales::percent_format())  
      theme(legend.position = "none") 
      theme(axis.text.x  = element_text(size = 10, angle=50)) 
    ggplot(score, aes(group, PT, fill = stain))  
     geom_bar(stat="identity", position = "fill") 
   scale_fill_manual(values = c("#ded9e2", "#c0b9dd", "#80a1d4", "#75c9c8")) 
      scale_y_continuous(labels = scales::percent_format())               
      theme_prism(base_size = 9) 
     theme(axis.text.x  = element_text(size = 10, angle=50))  
  • Related