Search code examples
rggplot2geom-bar

how to plot subsequent bars in a bar plot with ggplot2


I have the following dataframe called df1

Define the dataframe

df1 <- data.frame(
  trait = c("CRP", "CRP", "CRP", "TotChol", "TotChol", "TotChol", "RBC", "RBC", "RBC", "glucose", "glucose", "glucose"),
  Variable = c("PRSeur_r2_PGScatalog", "PRSeur_r2_mol", "moliPRS_eurPRS", 
               "PRSeur_r2_PGScatalog", "PRSeur_r2_mol", "moliPRS_eurPRS", 
               "PRSeur_r2_PGScatalog", "PRSeur_r2_mol", "moliPRS_eurPRS", 
               "PRSeur_r2_PGScatalog", "PRSeur_r2_mol", "moliPRS_eurPRS"),
  Value = c(14, 3.5, 3.9, 11, 9, 9.4, 15, 7, 8.11, 3, 1.3, 1.4)
)

Print the dataframe

print(df)

And I wrote the following code to have a bar plot:

ggplot(df1, aes(x = trait, y = Value, fill = Variable)) +
  geom_bar(stat = "identity", position = position_dodge(width = 0.9), col = "black") +
  geom_text(aes(label = paste0(Value, "%")), 
            position = position_dodge(width = 0.8), 
            vjust = -0.5, size = 3) + # Add percentages upon each bar
  scale_x_discrete(labels = c("CRP", 
                              "TotChol",
                              "RBC")) +
  scale_fill_manual(values = c("#39568CFF",
                               "#20A387FF", 
                               "#FDE725FF"),
                    labels = c("PRSeur_r2_moli" = "X",
                               "PRSeur_r2_PGScatalog" = "Y",
                               "moliPRS_eurPRS" = "Z")) +
  theme_bw() +
  theme(
    axis.text.y = element_text(size = 10),
    axis.text.x = element_text(size = 10),
    axis.title = element_text(size = 10, face = "bold"),
    legend.text = element_text(size = 10),
    panel.border = element_blank(),
    text = element_text(family = "Times New Roman")
  ) +
  labs(title = "",
       x = "",
       y = "r2",
       fill = NULL)

I have the following plot: enter image description here

I would like to create subsequent bar plots, maintaining the same size and position per each bar, as follows:

enter image description here enter image description here enter image description here

How can I do it with ggplot2 in R?


Solution

  • Put your plotting code in a function, set the Value for the undesired categories to NA and to silent the warnings about removed missing set na.rm=TRUE in the geoms:

    library(ggplot2)
    
    plot_fun <- function(include = NULL) {
      if (!is.null(include)) {
        df1 <- df1 |>
          transform(
            Value = ifelse(Variable %in% include, Value, NA)
          )
      }
    
      ggplot(df1, aes(x = trait, y = Value, fill = Variable)) +
        geom_bar(
          stat = "identity",
          position = position_dodge(width = 0.9),
          col = "black",
          na.rm = TRUE
        ) +
        geom_text(aes(label = paste0(Value, "%")),
          position = position_dodge(width = 0.8),
          vjust = -0.5, size = 3,
          na.rm = TRUE
        ) +
        scale_x_discrete(labels = c(
          "CRP",
          "TotChol",
          "RBC"
        )) +
        theme_bw() +
        theme(
          axis.text.y = element_text(size = 10),
          axis.text.x = element_text(size = 10),
          axis.title = element_text(size = 10, face = "bold"),
          legend.text = element_text(size = 10),
          panel.border = element_blank(),
          text = element_text(family = "Times New Roman")
        ) +
        labs(
          title = "",
          x = "",
          y = "r2",
          fill = NULL
        ) +
        scale_fill_manual(
          values = c(
            "#39568CFF",
            "#20A387FF",
            "#FDE725FF"
          ),
          labels = c(
            "PRSeur_r2_mol" = "X",
            "PRSeur_r2_PGScatalog" = "Y",
            "moliPRS_eurPRS" = "Z"
          )
        )
    }
    
    df1$Variable <- factor(
      df1$Variable,
      levels = c("PRSeur_r2_PGScatalog", "PRSeur_r2_mol", "moliPRS_eurPRS")
    )
    
    plot_fun("PRSeur_r2_PGScatalog")
    

    plot_fun(c("PRSeur_r2_mol", "PRSeur_r2_PGScatalog"))
    

    plot_fun()