繁体   English   中英

绘制箱线图时,使用ggplot2使多面x轴文本成为R中的分组因子

[英]Make the faceted x-axis text be the grouping factor in R using ggplot2 when plotting boxplots

我正在创建按变量分组的多面箱形图。 我希望x轴文本成为分组变量,而不是让x轴文本成为x轴变量的因素。

但是,我不只是想将分组变量用作我的x轴变量,因为我希望将箱形图进行聚类。 很难很好地解释。 但是我认为从下面的代码和注释中可以清楚地看出。

如果您有任何建议或可以帮助和感谢,请先告诉我!

    library(ggplot2) 
    library(scales)
    ln_clr <- "black"
    bk_clr <- "white"
    set.seed(1)

# Creates variables for a dataset
    donor = rep(paste0("Donor",1:3), each=40)
    machine = sample(rep(rep(paste0("Machine",1:4), each=1),30))
    gene = rep(paste0("Gene",LETTERS[1:5]), each=24)
    value = rnorm(24*5, mean=rep(c(0.5,10,1000,25000,8000), each=24), 
                  sd=rep(c(0.5,8,900,9000,3000), each=24))

# Makes all values positive
    for(m in 1:length(value)){
        if(value[m]<0){
            value[m] <- sqrt(value[m]*value[m])
        }
    }
# Creates a data frame from variables
    df = data.frame(donor, machine, gene, value)

# Adds a clone variable    
        clns <- LETTERS[1:4]
        k=1
        for(i in 1:nrow(df)/4){
            for(j in 1:length(clns)){
                df$clone[k] <- paste(df$donor[k],clns[j],sep="")
                    k = k+1
            }
        }
        df$clone <- as.factor(df$clone)


#*************************************************************************************************************************************
# Creates the facet of the machine but what I want on the x-axis is clone, not donor. 
# However, if I set x to clone it doesn't group the boxplots and its harder to read 
# the graph.
    bp1 <- ggplot(df, aes(x=donor, y=value, group=clone)) +
        stat_boxplot(geom ='errorbar', position = position_dodge(width = .83), 
                     width = 0.25, size = 0.7, coef = 1) +
        geom_boxplot(coef=1, outlier.shape = NA, position = position_dodge(width = .83), 
                     lwd = 0.3, alpha = 1, colour = ln_clr) +
        geom_point(position = position_dodge(width = 0.83), size = 1.8, alpha = 0.9, 
                    mapping=aes(group=clone)) +
        facet_wrap(~ machine, ncol=2, scales="free_x") 

    bp1 + scale_y_log10(expand = c(0, 0)) +
        theme(axis.text.x= element_text(size=rel(1), colour = "black", angle=45, hjust=1),
              strip.background = element_rect(colour = ln_clr, fill = bk_clr, size = 1))

# Creates the facet of the Donor and clusters the clones but doesn't facet the  
# machine. This could be okay if I could put spaces in between the different  
# machine values but not the donors and could remove the donor facet labels, and 
# only have the machine values show up once.
    bp2 <- ggplot(df, aes(x=clone, y=value)) +
        stat_boxplot(geom ='errorbar', position = position_dodge(width = .83),  
                     width = 0.25, size = 0.7, coef = 1) +
        geom_boxplot(coef=1, outlier.shape = NA, position = position_dodge(width = .83), 
                     lwd = 0.3, alpha = 1, colour = ln_clr) +
        geom_point(position = position_dodge(width = 0.83), size = 1.8, alpha = 0.9) +
        facet_wrap(machine ~ donor, scales="free_x", ncol=6) 

    bp2 + scale_y_log10(expand = c(0, 0)) +
        theme(axis.text.x= element_text(size=rel(1), colour = "black", angle=45, hjust=1),
              strip.background = element_rect(colour = ln_clr, fill = bk_clr, size = 1),
              panel.spacing = unit(0, "lines"))    

下面是一个示例,比较了我在理想世界中的需求(前两个方面)与获得的结果(下两个方面)之间的比较。

在此处输入图片说明

我不确定我确切了解您要做什么,所以请告诉我这是否正确:

library(dplyr)

pd = position_dodge(width=0.83)

ggplot(df %>% mutate(clone=gsub("Donor[1-3]","",clone),
                     donor=gsub("Donor", "", donor)), 
       aes(x=clone, y=value, color=donor, group=interaction(clone,donor))) +
  geom_boxplot(coef=1, outlier.shape=NA, position=pd, lwd=0.3) +
  geom_point(position=pd, size=1.8, alpha=0.9) +
  facet_wrap(~ machine, ncol=2, scales="free_x") +
  scale_y_log10(expand = c(0.02, 0)) +
  theme(strip.background=element_rect(colour=ln_clr, fill=bk_clr, size=1)) 

在此处输入图片说明

这个怎么样:

ggplot(df, aes(x=clone, y=value, group=interaction(clone,donor))) +
  geom_boxplot(coef=1, outlier.shape=NA, lwd=0.3) +
  geom_point(size=1.8, alpha=0.9) +
  facet_wrap(~ machine, ncol=2, scales="free_x") +
  scale_y_log10(expand = c(0.02, 0)) +
  theme(axis.text.x= element_text(size=rel(1), colour = "black", angle=45, hjust=1),
        strip.background=element_rect(colour=ln_clr, fill=bk_clr, size=1)) 

在此处输入图片说明

我找到了解决此问题的方法,但是它不是很优雅。 如果有人提出更好的解决方案,我将感到非常高兴。 使用代码为这里找到的“多图”创建函数,并在下面添加代码,我就能做到自己想要的。 但是,这是一个有点不方便的解决方案,因为我无法真正在标题周围加上框来格式化标题,并且在x轴上仍然有两个“克隆”标题,我无法轻易地用单个x轴标题来替换它们。 同样,如果我的示例中有许多“机器”,那么该解决方案很难扩展。 总而言之,这不是理想的选择,但对于我所需要的却可以接受。 特别感谢Eipi10的帮助,我非常感谢。

# Creates a multi-plot function for use in the graphs below   
multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
    library(grid)

    # Make a list from the ... arguments and plotlist
    plots <- c(list(...), plotlist)

    numPlots = length(plots)

    # If layout is NULL, then use 'cols' to determine layout
    if (is.null(layout)) {
        # Make the panel
        # ncol: Number of columns of plots
        # nrow: Number of rows needed, calculated from # of cols
        layout <- matrix(seq(1, cols * ceiling(numPlots/cols)),
                         ncol = cols, nrow = ceiling(numPlots/cols))
    }

    if (numPlots==1) {
        print(plots[[1]])

    } else {
        # Set up the page
        grid.newpage()
        pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))

        # Make each plot, in the correct location
        for (i in 1:numPlots) {
            # Get the i,j matrix positions of the regions that contain this subplot
            matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))

            print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row,
                                            layout.pos.col = matchidx$col))
        }
    }
}

    # Call multiplot function after storing each of the below plots as variables
    ln_clr <- "black"
    bk_clr <- "white"

    bp3 <- ggplot(df[df$machine=="Machine1",], aes(x=clone, y=value)) +
        geom_boxplot(coef=1, outlier.shape=NA, lwd=0.3) +
        geom_point(size=1.8, alpha=0.9) +
        ggtitle("Machine 1") + 
        expand_limits(y=c(0.001,10^5)) +
        facet_wrap(~ donor, nrow=1, scales="free_x") + scale_y_log10(expand = c(0, 0)) +
        theme(axis.text.x= element_text(size=rel(1), color = ln_clr, angle=45, hjust=1),
              panel.spacing = unit(0.25, "lines"), axis.title.x= element_blank(),
              plot.title = element_text(hjust=0.5), 
              strip.text.x = element_text(size=rel(1), face="bold", colour = ln_clr),
              strip.background = element_rect(colour = ln_clr, fill = bk_clr, size = 1),
              axis.line.x= element_line(size = 1.25, colour = ln_clr),
              axis.line.y= element_line(size = 1.25, colour = ln_clr),
              panel.grid.major = element_blank(), 
              panel.grid.minor = element_blank(), 
              panel.background = element_rect(fill = bk_clr),
              panel.border = element_blank(),
              plot.background = element_rect(fill = bk_clr))

    bp4 <- ggplot(df[df$machine=="Machine2",], aes(x=clone, y=value)) +
        geom_boxplot(coef=1, outlier.shape=NA, lwd=0.3) +
        geom_point(size=1.8, alpha=0.9) +
        ggtitle("Machine 2") + 
        expand_limits(y=c(0.001,10^5)) +
        facet_wrap(~ donor, nrow=1, scales="free_x") + scale_y_log10(expand = c(0, 0)) +
        theme(axis.text.x= element_text(size=rel(1), colour = ln_clr, angle=45, hjust=1),
              panel.spacing = unit(0.25, "lines"), plot.title = element_text(hjust=0.5),
              strip.text.x = element_text(size=rel(1), face="bold", colour = ln_clr),
              strip.background = element_rect(colour = ln_clr, fill = bk_clr, size = 1),
              axis.line.x= element_line(size = 1.25, colour = ln_clr),
              axis.line.y= element_line(size = 1.25, colour = ln_clr),
              panel.grid.major = element_blank(), 
              panel.grid.minor = element_blank(), 
              panel.background = element_rect(fill = bk_clr),
              panel.border = element_blank(),
              plot.background = element_rect(fill = bk_clr))

    bp5 <- ggplot(df[df$machine=="Machine3",], aes(x=clone, y=value)) +
        geom_boxplot(coef=1, outlier.shape=NA, lwd=0.3) +
        geom_point(size=1.8, alpha=0.9) +
        ggtitle("Machine 3") + 
        expand_limits(y=c(0.001,10^5)) +
        facet_wrap(~ donor, nrow=1, scales="free_x") + scale_y_log10(expand = c(0, 0)) +
        theme(panel.spacing = unit(0.25, "lines"), axis.title.y= element_blank(),
              axis.title.x= element_blank(),axis.line.y= element_blank(),
              axis.text.y=element_blank(),
              axis.text.x= element_text(size=rel(1), colour = ln_clr, angle=45, hjust=1),
              axis.ticks.y=element_blank(), plot.title = element_text(hjust=0.5),
              strip.text.x = element_text(size=rel(1), face="bold", colour = ln_clr),
              strip.background = element_rect(colour = ln_clr, fill = bk_clr, size = 1),
              axis.line.x= element_line(size = 1.25, colour = ln_clr),
              panel.grid.major = element_blank(), 
              panel.grid.minor = element_blank(), 
              panel.background = element_rect(fill = bk_clr),
              panel.border = element_blank(),
              plot.background = element_rect(fill = bk_clr))

    bp6 <- ggplot(df[df$machine=="Machine4",], aes(x=clone, y=value)) +
        geom_boxplot(coef=1, outlier.shape=NA, lwd=0.3) +
        geom_point(size=1.8, alpha=0.9) +
        ggtitle("Machine 4") + 
        expand_limits(y=c(0.001,10^5)) +
        facet_wrap(~ donor, nrow=1, scales="free_x") + scale_y_log10(expand = c(0, 0)) +
        theme(axis.text.x= element_text(size=rel(1), colour = ln_clr, angle=45, hjust=1),
              panel.spacing = unit(0.25, "lines"), plot.title = element_text(hjust=0.5),
              strip.text.x = element_text(size=rel(1), face="bold", colour = ln_clr),
              strip.background = element_rect(colour = ln_clr, fill = bk_clr, size = 1),
              axis.line.x= element_line(size = 1.25, colour = ln_clr),
              axis.line.y= element_blank(),
              axis.text.y=element_blank(),
              axis.ticks.y=element_blank(),
              axis.title.y= element_blank(),
              panel.grid.major = element_blank(), 
              panel.grid.minor = element_blank(), 
              panel.background = element_rect(fill = bk_clr),
              panel.border = element_blank(),
              plot.background = element_rect(fill = bk_clr))

# Plot all 4 graphs and saves them as a output file  
    png(filename="graph3.png", width= 9, height= 7.5, units = "in", res=600)
    multiplot(bp3, bp4, bp5, bp6, cols=2)
    dev.off()

在此处输入图片说明

另外,如果我将“ strip.text.x =”和“ strip.background =”设置为element_blank()。 我可以生成以下内容:

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM