How to show all the labels in X-axis 45 degree in R 2x2 bar plot

前端 未结 4 1534
独厮守ぢ
独厮守ぢ 2020-12-20 05:20

With the following data:

Method  Metric  E0  E1  E2  E4
Method-XXX  Precision   0.9661017   0.9622642   1   0.9655172
Method-YYY  Precision   0.533   0.535           


        
相关标签:
4条回答
  • 2020-12-20 05:49

    Following basically the same strategy used in this answer (and demo'd in the first example in the gridBase vignette (pdf)) you could use grid.text() to annotate the base graphics output.

    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)
    

    enter image description here

    0 讨论(0)
  • 2020-12-20 06:05

    With the reshape2 (for reshaping your data into long format) and ggplot2 (for plotting) packages, it will be quite a lot easier to make such a plot.

    The code:

    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)
      )
    

    The result: enter image description here

    When you want to keep axis-labels on each seperate plot, you'll need the ggplot2 and gridExtra packages.

    The code:

    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)
    

    The result: enter image description here

    0 讨论(0)
  • 2020-12-20 06:06

    add to rotate 45 degrees

    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)
    

    add this to rotate 180 degrees the labels 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)
    
    0 讨论(0)
  • 2020-12-20 06:15

    Here's a way to get all the labels without rotating. You plot the axis labels on two lines instead of one to avoid overlap. I've done it with a single graph to demonstrate the method.

    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)
    
    0 讨论(0)
提交回复
热议问题