How to add axis text in this negative and positive bars differently using ggplot2?

I drew a bar chart with negative and positive bars that are familiar with the study . However, my code seems extremely inconvenient and detailed using graphics::plot() and graphics::text() , as shown below. Try it, I can find a solution using element_text to execute in ggplot2 . Please help or try to give some ideas on how to achieve this in ggplot2 . Thanks in advance. enter image description here

 # my data df <- data.frame(genus=c("Prevotella","Streptococcus","YRC22","Phascolarctobacterium","SMB53","Epulopiscium", "CF231","Anaerovibrio","Paludibacter","Parabacteroides","Desulfovibrio","Sutterella", "Roseburia","Others__0_5_","Akkermansia","Bifidobacterium","Campylobacter","Fibrobacter", "Coprobacillus","Bulleidia","f_02d06","Dorea","Blautia","Enterococcus","Eubacterium", "p_75_a5","Clostridium","Coprococcus","Oscillospira","Escherichia","Lactobacillus"), class=c(rep("groupA",18),rep("groupB",13)), value=c(4.497311,4.082377,3.578472,3.567310,3.410453,3.390026, 3.363542,3.354532,3.335634,3.284165,3.280838,3.218053, 3.071454,3.026663,3.021749,3.004152,2.917656,2.811455, -2.997631,-3.074314,-3.117659,-3.151276,-3.170631,-3.194323, -3.225207,-3.274281,-3.299712,-3.299875,-3.689051,-3.692055, -4.733154) ) # bar graph tiff(file="lefse.tiff",width=2000,height=2000,res=400) par(mar=c(5,2,1,1)) barplot(df[,3],horiz=T,xlim=c(-6,6),xlab="LDA score (log 10)", col=c(rep("forestgreen",length(which(df[,2]=="groupA"))), rep("goldenrod",length(which(df[,2]=="groupB"))))) axis(1,at=seq(-6,6,by=1)) # add text text(0.85,36.7,label=df[,1][31],cex=0.6);text(0.75,35.4,label=df[,1][30],cex=0.6) text(0.75,34.1,label=df[,1][29],cex=0.6);text(0.85,33.0,label=df[,1][28],cex=0.6) text(0.75,31.8,label=df[,1][27],cex=0.6);text(0.6,30.6,label=df[,1][26],cex=0.6) text(0.8,29.5,label=df[,1][25],cex=0.6);text(0.85,28.3,label=df[,1][24],cex=0.6) text(0.45,27.1,label=df[,1][23],cex=0.6);text(0.4,25.9,label=df[,1][22],cex=0.6) text(0.55,24.7,label=df[,1][21],cex=0.6);text(0.55,23.5,label=df[,1][20],cex=0.6) text(0.85,22.3,label=df[,1][19],cex=0.6);text(-0.75,21.1,label=df[,1][18],cex=0.6) text(-1,19.9,label=df[,1][17],cex=0.6);text(-1,18.8,label=df[,1][16],cex=0.6) text(-0.85,17.6,label=df[,1][15],cex=0.6);text(-0.85,16.3,label=df[,1][14],cex=0.6) text(-0.7,15.1,label=df[,1][13],cex=0.6);text(-0.65,13.9,label=df[,1][12],cex=0.6) text(-0.85,12.7,label=df[,1][11],cex=0.6);text(-1.05,11.5,label=df[,1][10],cex=0.6) text(-0.85,10.3,label=df[,1][9],cex=0.6);text(-0.85,9.1,label=df[,1][8],cex=0.6) text(-0.47,7.9,label=df[,1][7],cex=0.6);text(-0.85,6.7,label=df[,1][6],cex=0.6) text(-0.49,5.5,label=df[,1][5],cex=0.6);text(-1.44,4.3,label=df[,1][4],cex=0.6) text(-0.49,3.1,label=df[,1][3],cex=0.6);text(-0.93,1.9,label=df[,1][2],cex=0.6) text(-0.69,0.7,label=df[,1][1],cex=0.6) # add lines segments(0,-1,0,40,lty=3,col="grey") segments(2,-1,2,40,lty=3,col="grey") segments(4,-1,4,40,lty=3,col="grey") segments(6,-1,6,40,lty=3,col="grey") segments(4,-1,4,40,lty=3,col="grey") segments(-2,-1,-2,40,lty=3,col="grey") segments(-4,-1,-4,40,lty=3,col="grey") segments(-6,-1,-6,40,lty=3,col="grey") legend("topleft",bty="n",cex=0.65,inset=c(0.01,-0.02),ncol=2, legend=c("groupA","groupB"), col=c("forestgreen", "goldenrod"),pch=c(15,15)) dev.off() 
+6
source share
3 answers

Here is a solution that uses dplyr to create additional columns for the position of the label and its rationale, and then to ensure that the plot matches what you originally had:

 library("dplyr") library("ggplot2") df <- df %>% mutate( genus = factor(genus, levels = genus[order(value, decreasing = TRUE)]), label_y = ifelse(value < 0, 0.2, -0.2), label_hjust = ifelse(value < 0, 0, 1) ) my_plot <- ggplot(df, aes(x = genus, y = value, fill = class)) + geom_bar(stat = "identity", col = "black") + geom_text(aes(y = label_y, label = genus, hjust = label_hjust)) + coord_flip() + scale_fill_manual(values = c(groupA = "forestgreen", groupB = "goldenrod")) + theme_minimal() + theme(axis.text.y = element_blank(), axis.ticks.y = element_blank(), axis.title.y = element_blank(), legend.position = "top", legend.justification = 0.05, legend.title = element_blank(), panel.grid.major.y = element_blank(), panel.grid.minor.y = element_blank(), panel.grid.major.x = element_line(colour = "grey80", linetype = "dashed"), panel.grid.minor.x = element_blank()) + scale_y_continuous(expression(log[10](italic("LDA score"))), breaks = -6:6, limits = c(-6, 6)) print(my_plot) ggsave("lefse.tiff", width = 5, height = 5, dpi = 400, my_plot) 

enter image description here

+4
source

I would try this:

 library(ggplot2) # change the factor levels so it will be displayed in correct order df$genus <- factor(df$genus, levels = as.character(df$genus)) ggplot(df, aes(x = genus, y = value)) + geom_bar(aes(fill = class), stat = 'identity') + # color by class coord_flip() + # horizontal bars geom_text(aes(y = 0, label = genus, hjust = as.numeric(value > 0))) + # label text based on value theme(axis.text.y = element_blank()) 

enter image description here

In the above text, hjust will change the direction of the text relative to its position y (now flipped to x), which is similar to the pos parameter in the base graph R. Thus, the code can also be simplified by using the argument vector pos for the text function.

+4
source

Two options:

 library(ggplot2) # my data df <- data.frame(genus=c("Prevotella","Streptococcus","YRC22","Phascolarctobacterium","SMB53","Epulopiscium", "CF231","Anaerovibrio","Paludibacter","Parabacteroides","Desulfovibrio","Sutterella", "Roseburia","Others__0_5_","Akkermansia","Bifidobacterium","Campylobacter","Fibrobacter", "Coprobacillus","Bulleidia","f_02d06","Dorea","Blautia","Enterococcus","Eubacterium", "p_75_a5","Clostridium","Coprococcus","Oscillospira","Escherichia","Lactobacillus"), class=c(rep("groupA",18),rep("groupB",13)), value=c(4.497311,4.082377,3.578472,3.567310,3.410453,3.390026, 3.363542,3.354532,3.335634,3.284165,3.280838,3.218053, 3.071454,3.026663,3.021749,3.004152,2.917656,2.811455, -2.997631,-3.074314,-3.117659,-3.151276,-3.170631,-3.194323, -3.225207,-3.274281,-3.299712,-3.299875,-3.689051,-3.692055, -4.733154) ) ggplot(df, aes(reorder(genus, -value), value, fill = class)) + geom_bar(stat = "identity") + coord_flip() + geom_text(aes(label = genus, y = ifelse(value < 1, 1.5, -1.5)), size = 2.5) + theme(axis.title.y=element_blank(), axis.text.y=element_blank(), axis.ticks.y=element_blank()) 

enter image description here

Or that:

 library(ggplot2) # my data df <- data.frame(genus=c("Prevotella","Streptococcus","YRC22","Phascolarctobacterium","SMB53","Epulopiscium", "CF231","Anaerovibrio","Paludibacter","Parabacteroides","Desulfovibrio","Sutterella", "Roseburia","Others__0_5_","Akkermansia","Bifidobacterium","Campylobacter","Fibrobacter", "Coprobacillus","Bulleidia","f_02d06","Dorea","Blautia","Enterococcus","Eubacterium", "p_75_a5","Clostridium","Coprococcus","Oscillospira","Escherichia","Lactobacillus"), class=c(rep("groupA",18),rep("groupB",13)), value=c(4.497311,4.082377,3.578472,3.567310,3.410453,3.390026, 3.363542,3.354532,3.335634,3.284165,3.280838,3.218053, 3.071454,3.026663,3.021749,3.004152,2.917656,2.811455, -2.997631,-3.074314,-3.117659,-3.151276,-3.170631,-3.194323, -3.225207,-3.274281,-3.299712,-3.299875,-3.689051,-3.692055, -4.733154) ) ggplot(df, aes(reorder(genus, -value), value, fill = class)) + geom_bar(stat = "identity") + coord_flip() + xlab("genus") 

enter image description here

+1
source

Source: https://habr.com/ru/post/1015556/


All Articles