【问题标题】:How to show all the labels in X-axis 45 degree in R 2x2 bar plot如何在 R 2x2 条形图中显示 X 轴 45 度的所有标签
【发布时间】:2026-02-15 01:50:01
【问题描述】:

有以下数据:

Method  Metric  E0  E1  E2  E4
Method-XXX  Precision   0.9661017   0.9622642   1   0.9655172
Method-YYY  Precision   0.533   0.535   0.378   0.214
Method-ZZZ  Precision  0.595    0.843   0.77    0.689
Method-XZZZ Precision   0.573   0.698   0.53    0.708
Method-XZZZY    Precision   0.008   0.011   0.004   0.002
Method-XXX  Recall  0.9736842   0.9736842   0.9473684   0.9473684
Method-YYY     Recall   1   1   1   0.667
Method-ZZZ  Recall       0.833  1   1   1
Method-XZZZ Recall  1   1   1   1
Method-XZZZY    Recall  0.167   0.75    1   1

我可以创建这个情节:

但是,如您所见,x 轴并非都分配有标签。 我怎样才能做到这一点? 如果我们将 x 轴旋转 45 度也可以。但是我不知道该怎么做:

这是我的代码(thelatemail 提供):

dat <- read.table("http://dpaste.com/1563769/plain/",header=TRUE)
layout(matrix(c(1,2,5,3,4,5),nrow=2,byrow = TRUE))
barcols <- c("red","blue")

sapply(3:6, 
  function(x) {
    bp <- barplot(matrix(dat[,x],nrow=2,byrow=TRUE),beside=TRUE,col=barcols)
    title(main=names(dat[x]))
    axis(1,at=colMeans(bp),c("Method-XXX","Method-YYY"," Method-ZZZ","Method-XZZZ"," Method-XZZZY"),lwd=0,lwd.tick=1)
    abline(h=0)
  }
)

plot(NA,xlim=c(0,1),ylim=c(0,1),ann=FALSE,axes=FALSE)
legend(0,0.6,c("Precision","Recall"),fill=barcols,cex=1.5)

更新

我尝试了以下方法来生成 45 度。但也没有用:

sapply(3:6,
  function(x) {
    bp <- barplot(matrix(dat[,x],nrow=2,byrow=TRUE),xaxt="n",beside=TRUE,col=barcols)
    title(main=names(dat[x]))
    xaxislab <- c("Method-XXX","Method-YYY"," Method-ZZZ","Method-XZZZ"," Method-XZZZY")
    text(cex=1, x=colMeans(bp)-.25, y=-1.25, xaxislab, xpd=TRUE, srt=45)
    #axis(1,at=colMeans(bp),xaxislab,lwd=0,lwd.tick=1)
    #abline(h=0)
  }
)
plot(NA,xlim=c(0,1),ylim=c(0,1),ann=FALSE,axes=FALSE)
legend(0,0.1,c("Precision","Recall"),fill=barcols,cex=1.5)

【问题讨论】:

    标签: r plot bar-chart


    【解决方案1】:

    添加旋转45度

    dat <- read.table("http://dpaste.com/1563769/plain/",header=TRUE)
    layout(matrix(c(1,2,5,3,4,5),nrow=2,byrow = TRUE))
    barcols <- c("red","blue")
    
    sapply(3:6, 
           function(x) {
             #par(las = 2)
             bp <- barplot(matrix(dat[,x],nrow=2,byrow=TRUE),beside=TRUE,col=barcols)
             title(main=names(dat[x]))
            #axis(1,at=colMeans(bp),lwd=0,lwd.tick=1,srt=45)
            text(colMeans(bp), par("usr")[3] , labels = c("Method-XXX","Method-YYY"," Method-ZZZ","Method-XZZZ"," Method-XZZZY"), srt = 45, pos = 1, xpd = TRUE)
    
    
             abline(h=0)
           }
    )
    
    plot(NA,xlim=c(0,1),ylim=c(0,1),ann=FALSE,axes=FALSE)
    legend(0,0.6,c("Precision","Recall"),fill=barcols,cex=1.5)
    

    添加这个以将标签旋转 180 度 par(las = 2)

    dat <- read.table("http://dpaste.com/1563769/plain/",header=TRUE)
        layout(matrix(c(1,2,5,3,4,5),nrow=2,byrow = TRUE))
        barcols <- c("red","blue")
    
    sapply(3:6, 
           function(x) {
    #add this to rotate the labels
             par(las = 2)
             bp <- barplot(matrix(dat[,x],nrow=2,byrow=TRUE),beside=TRUE,col=barcols)
             title(main=names(dat[x]))
             axis(1,at=colMeans(bp),c("Method-XXX","Method-YYY"," Method-ZZZ","Method-XZZZ"," Method-XZZZY"),lwd=0,lwd.tick=1)
             abline(h=0)
           }
    )
    
    plot(NA,xlim=c(0,1),ylim=c(0,1),ann=FALSE,axes=FALSE)
    legend(0,0.6,c("Precision","Recall"),fill=barcols,cex=1.5)
    

    【讨论】:

    • 谢谢,但是 180 度的旋转太强了。我希望它最多 45 度。
    • 45度可以查看*.com/questions/20241388/…
    • 我已经更新了 45 度...希望它会有所帮助
    【解决方案2】:

    这是一种无需旋转即可获取所有标签的方法。您将轴标签绘制在两条线上而不是一条线上以避免重叠。我用一张图来演示这个方法。

    dat <- read.table("http://dpaste.com/1563769/plain/",header=TRUE)
    
    # Create barplot
    barplot(height=dat$E0, beside=TRUE, col=c("red","blue"))
    
    # Get x-coordinates of bars
    x.coords = barplot(height=dat$E0, beside=TRUE, plot=FALSE)
    # Create new coordinates between each pair of bars
    new.x.coords = seq(sum(x.coords)[1:2]/2, sum(x.coords)[9:10]/2, x.coords[2]-x.coords[1])
    
    # Plot axis labels, but not axis or tickmarks
    axis(side=1, at=new.x.coords[c(1,3,5)], labels=dat$Method[c(1,3,5)], line=0, tick=FALSE)
    axis(side=1, at=new.x.coords[c(2,4)], labels=dat$Method[c(2,4)], line=1, tick=FALSE)
    # Plot just axis and tickmarks, but not labels
    axis(side=1, at=new.x.coords, labels=NA)
    

    【讨论】:

      【解决方案3】:

      使用reshape2(用于将数据重新整形为长格式)和ggplot2(用于绘图)包,制作这样的绘图会容易得多。

      代码:

      dat <- read.table("http://dpaste.com/1563769/plain/",header=TRUE)
      
      library(reshape2)
      library(ggplot2)
      
      # reshape your data into long format
      long <- melt(dat, id=c("Method","Metric"), 
                   measure=c("E0","E1","E2","E4"),
                   variable = "E.nr")
      
      # make the plot
      ggplot(long) +
        geom_bar(aes(x = Method, y = value, fill = Metric), 
                 stat="identity", position = "dodge", width = 0.7) +
        facet_wrap(~E.nr) +
        scale_fill_manual("Metric\n", values = c("red","blue"), 
                          labels = c(" Precision", " Recall")) +
        labs(x="",y="") +
        theme_bw() +
        theme(
          panel.grid.major.y = element_line(colour = "black", linetype = 3, size = .5),
          panel.background = element_blank(),
          axis.title.x = element_text(size=16),
          axis.text.x = element_text(size=14, angle=45, hjust=1, vjust=1),
          axis.title.y = element_text(size=16, angle = 90),
          axis.text.y = element_text(size=14),
          strip.background = element_rect(color="white", fill="white"),
          strip.text = element_text(size=16)
        )
      

      结果:

      当您想在每个单独的图上保留轴标签时,您需要 ggplot2gridExtra 包。

      代码:

      dat <- read.table("http://dpaste.com/1563769/plain/",header=TRUE)
      
      library(ggplot2)
      library(gridExtra)
      
      # making the seperate plots 
      pE0 <- ggplot(dat) +
        geom_bar(aes(x = Method, y = E0, fill = Metric), 
                 stat="identity", position = "dodge", width = 0.7) +
        scale_fill_manual("Metric\n", values = c("red","blue"), 
                          labels = c(" Precision", " Recall")) +
        labs(title="E0\n",x="",y="") +
        theme_bw() +
        theme(
          panel.grid.major.y = element_line(colour = "black", linetype = 3, size = .5),
          panel.background = element_blank(),
          axis.title.x = element_text(size=16),
          axis.text.x = element_text(size=14, angle=30, hjust=1, vjust=1),
          axis.title.y = element_text(size=16, angle = 90),
          axis.text.y = element_text(size=14)
        )
      
      pE1 <- ggplot(dat) +
        geom_bar(aes(x = Method, y = E1, fill = Metric), 
                 stat="identity", position = "dodge", width = 0.7) +
        scale_fill_manual("Metric\n", values = c("red","blue"), 
                          labels = c(" Precision", " Recall")) +
        labs(title="E1\n",x="",y="") +
        theme_bw() +
        theme(
          panel.grid.major.y = element_line(colour = "black", linetype = 3, size = .5),
          panel.background = element_blank(),
          axis.title.x = element_text(size=16),
          axis.text.x = element_text(size=14, angle=30, hjust=1, vjust=1),
          axis.title.y = element_text(size=16, angle = 90),
          axis.text.y = element_text(size=14)
        )
      
      pE2 <- ggplot(dat) +
        geom_bar(aes(x = Method, y = E2, fill = Metric), 
                 stat="identity", position = "dodge", width = 0.7) +
        scale_fill_manual("Metric\n", values = c("red","blue"), 
                          labels = c(" Precision", " Recall")) +
        labs(title="E2\n",x="",y="") +
        theme_bw() +
        theme(
          panel.grid.major.y = element_line(colour = "black", linetype = 3, size = .5),
          panel.background = element_blank(),
          axis.title.x = element_text(size=16),
          axis.text.x = element_text(size=14, angle=30, hjust=1, vjust=1),
          axis.title.y = element_text(size=16, angle = 90),
          axis.text.y = element_text(size=14)
        )
      
      pE4 <- ggplot(dat) +
        geom_bar(aes(x = Method, y = E4, fill = Metric), 
                 stat="identity", position = "dodge", width = 0.7) +
        scale_fill_manual("Metric\n", values = c("red","blue"), 
                          labels = c(" Precision", " Recall")) +
        labs(title="E4\n",x="",y="") +
        theme_bw() +
        theme(
          panel.grid.major.y = element_line(colour = "black", linetype = 3, size = .5),
          panel.background = element_blank(),
          axis.title.x = element_text(size=16),
          axis.text.x = element_text(size=14, angle=30, hjust=1, vjust=1),
          axis.title.y = element_text(size=16, angle = 90),
          axis.text.y = element_text(size=14)
        )
      
      # function to extract the legend (borrowed from: https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs )
      g_legend<-function(a.gplot){
        tmp <- ggplot_gtable(ggplot_build(a.gplot))
        leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
        legend <- tmp$grobs[[leg]]
        return(legend)}
      
      legend <- g_legend(pE1)
      lwidth <- sum(legend$width)
      
      # combining the plots with gridExtra
      grid.arrange(arrangeGrob(pE0 + theme(legend.position="none"),
                               pE1 + theme(legend.position="none"),
                               pE2 + theme(legend.position="none"),
                               pE4 + theme(legend.position="none")
                               ), 
                   legend, widths=unit.c(unit(1, "npc") - lwidth, lwidth), nrow=1)
      

      结果:

      【讨论】:

        【解决方案4】:

        遵循this answer 中使用的基本相同策略(并在gridBase vignette (pdf) 的第一个示例中演示),您可以使用grid.text() 来注释base 图形输出。 p>

        library(gridBase)
        
        ## Function that plots barplots with x-axes annotated with slanted
        ff <- function(x) {
            barcols <- c("red","blue")
        
            ## Plot, suppressing the labels
            bp <- barplot(matrix(dat[,x], nrow = 2, byrow = TRUE), xaxt = "n",
                          beside = TRUE, col = barcols)
            title(main=names(dat[x]))
            xaxislab <- c("Method-XXX", "Method-YYY", " Method-ZZZ",
                          "Method-XZZZ", " Method-XZZZY")
        
            ## Compute x-axis coordinate at center of each group
            bp <- colMeans(bp) 
        
            ## Use gridBase to compute viewport coordinates and
            ## grid to push/pop viewports and add the labels
            vps <- baseViewports()
            pushViewport(vps$inner, vps$figure, vps$plot)
            grid.text(xaxislab,
                x = unit(bp, "native"), y = unit(-0.5, "lines"),
                just = "right", rot = 45, gp=gpar(cex=0.7))
            popViewport(3)
        }
        
        ## Apply it to your data 
        dat <- read.table("http://dpaste.com/1563769/plain/",header=TRUE)
        layout(matrix(c(1,2,5,3,4,5),nrow=2,byrow = TRUE))
        sapply(3:6, ff)
        

        【讨论】: