Search code examples
rggplot2ggpubrrstatix

Move p values to extremes of bar plot ggpubr/rstatix


I've created a bar plot using ggpubr to display a fold increase or decrease compared to a control. I am trying to add the p values to this plot but as the plot contains both positive and negative bars I cannot manage to get the p values located at the extremens of all bars. This is what the plot looks like now

enter image description here

This is the code I am using:

library(ggpubr)
library(rstatix)
library(plyr)

clust <- c(2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9)
clust <- as.factor(clust)
difference <- c(-1.62946364, -0.33442372, -1.39733564, -6.50845208, -2.51526275, -0.93206327, -0.56179492,  9.66283529, -0.01552568,  7.28771312, -3.24222047, -6.04470411,  4.09404411, -0.88665735,  5.26755900, -2.24424787)
df <- data.frame(cluster2 = clust, dif = difference)


pplot <- ggbarplot(df, x = "cluster2", y = "dif",
                       fill = "cluster2",
                       palette = c("gold3","darkolivegreen3","seagreen3", "forestgreen","dodgerblue","cyan1","indianred","firebrick","brown1"),
                       rotate = TRUE,
                       add = "mean_se") +
      scale_x_discrete(limits = rev)

stat_val <- df %>% 
        group_by(cluster2) %>%
        wilcox_test(dif ~ 1) %>%
        adjust_pvalue() %>%
        add_significance("p.adj")

stat_val <- stat_val %>% add_xy_position(fun = "mean_se", x = "cluster2")
p <- pplot + stat_pvalue_manual(stat_val, x = "cluster2", label = "p.adj.signif")
p

Solution

  • are u looking for this one

    library(ggpubr)
    library(rstatix)
    library(plyr)
    
    clust <- c(2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9)
    clust <- as.factor(clust)
    difference <- c(-1.62946364, -0.33442372, -1.39733564, -6.50845208, -2.51526275, -0.93206327, -0.56179492,  9.66283529, -0.01552568,  7.28771312, -3.24222047, -6.04470411,  4.09404411, -0.88665735,  5.26755900, -2.24424787)
    df <- data.frame(cluster2 = clust, dif = difference)
    
    pplot <- ggbarplot(df, x = "cluster2", y = "dif",
                       fill = "cluster2",
                       palette = c("gold3","darkolivegreen3","seagreen3", "forestgreen","dodgerblue","cyan1","indianred","firebrick","brown1"),
                       rotate = TRUE,
                       add = "mean_se") +
      scale_x_discrete(limits = rev)
    
    # Calculate p-values and add significance labels
    stat_val <- df %>%
      group_by(cluster2) %>%
      wilcox_test(dif ~ 1) %>%
      adjust_pvalue() %>%
      add_significance("p.adj") %>%
      add_xy_position(fun = "mean_se", x = "cluster2")
    
    # Manually set the position based on the y-axis range
    y_range <- range(df$dif)
    position_y <- y_range[2] + 0.1 * diff(y_range)  # Adjust the multiplier as needed
    
    # Add p-values to the plot using geom_text
    p <- pplot + 
      geom_text(data = stat_val, aes(x = cluster2, y = position_y, label = paste0("p = ", round(p.adj, 3))),
                position = position_dodge(width = 0.75), vjust = -0.5, size = 3)
    
    print(p)
    

    enter image description here