如何自动调整facet_wrap的每个构面的宽度? [英] How to automatically adjust the width of each facet for facet_wrap?

查看:334
本文介绍了如何自动调整facet_wrap的每个构面的宽度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用ggplot2绘制箱形图,并且我有多个面,每个面都有不同的用语,如下所示:

I want to plot a boxplot using ggplot2, and i have more than one facet, each facet has different terms, as follows:

library(ggplot2)

  p <- ggplot(
    data=Data,
    aes(x=trait,y=mean)
    )

  p <- p+facet_wrap(~SP,scales="free",nrow=1)

  p <- p+geom_boxplot(aes(fill = Ref,
    lower = mean - sd, 
    upper = mean + sd, 
    middle = mean, 
    ymin = min, 
    ymax = max,
    width=c(rep(0.8/3,3),rep(0.8,9))),
    lwd=0.5,
    stat="identity")

如图所示,不同面中的框的宽度不相同,有没有办法以相同的比例调整所有框?我尝试使用facet_grid,它可以自动更改构面的宽度,但是所有构面共享相同的y轴.

as showed, the width of box in different facet is not the same, is there any way to adjust all the box at a same scale? I had tried to use facet_grid, it can automatically change the width of facets, but all facets share the same y axis.

数据

Data <- structure(list(SP = structure(c(3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 
    4L, 4L, 4L, 4L), .Label = c("Human", "Cattle", "Horse", "Maize"
    ), class = "factor"), Ref = structure(c(3L, 2L, 1L, 3L, 3L, 3L, 
    2L, 2L, 2L, 1L, 1L, 1L), .Label = c("LMM", "Half", "Adoptive"
    ), class = "factor"), trait = structure(c(11L, 11L, 11L, 14L, 
    13L, 12L, 14L, 13L, 12L, 14L, 13L, 12L), .Label = c("cad", "ht", 
    "t2d", "bd", "cd", "ra", "t1d", "fpro", "mkg", "scs", "coat colour", 
    "ywk", "ssk", "gdd"), class = "factor"), min = c(0.324122039, 
    0.336486555, 0.073152049, 0.895455441, 0.849944623, 0.825248005, 
    0.890413591, 0.852385351, 0.826470308, 0.889139116, 0.838256672, 
    0.723753592), max = c(0.665536838, 0.678764774, 0.34033228, 0.919794865, 
    0.955018001, 0.899903826, 0.913350912, 0.957305688, 0.89843716, 
    0.911257005, 0.955312678, 0.817489555), mean = c(0.4919168555, 
    0.5360103372, 0.24320509565, 0.907436221, 0.9057516121, 0.8552899502, 
    0.9035394117, 0.9068819173, 0.8572309823, 0.90125638965, 0.90217769835, 
    0.7667208778), sd = c(0.0790133656517775, 0.09704320004497, 0.0767552215753863, 
    0.00611921020505611, 0.0339614482273291, 0.0199389195311925, 
    0.00598633573504195, 0.0332634006653858, 0.0196465508521771, 
    0.00592476494699222, 0.0348144156099722, 0.0271827880539459)), .Names = c("SP", 
    "Ref", "trait", "min", "max", "mean", "sd"), class = "data.frame", row.names =                 c(10L, 
    11L, 12L, 34L, 35L, 36L, 37L, 38L, 39L, 40L, 41L, 42L))

推荐答案

将ggplot对象转换为grob后,您可以调整构面宽度:

You can adjust facet widths after converting the ggplot object to a grob:

# create ggplot object (no need to manipulate boxplot width here. 
# we'll adjust the facet width directly later)
p <- ggplot(Data,
       aes(x = trait, y = mean)) +
  geom_boxplot(aes(fill = Ref,
                   lower = mean - sd, 
                   upper = mean + sd, 
                   middle = mean, 
                   ymin = min, 
                   ymax = max),
               lwd = 0.5,
               stat = "identity") +
  facet_wrap(~ SP, scales = "free", nrow = 1) +
  scale_x_discrete(expand = c(0, 0.5)) + # change additive expansion from default 0.6 to 0.5
  theme_bw()

# convert ggplot object to grob object
gp <- ggplotGrob(p)

# optional: take a look at the grob object's layout
gtable::gtable_show_layout(gp)

# get gtable columns corresponding to the facets (5 & 9, in this case)
facet.columns <- gp$layout$l[grepl("panel", gp$layout$name)]

# get the number of unique x-axis values per facet (1 & 3, in this case)
x.var <- sapply(ggplot_build(p)$layout$panel_scales_x,
                function(l) length(l$range$range))

# change the relative widths of the facet columns based on
# how many unique x-axis values are in each facet
gp$widths[facet.columns] <- gp$widths[facet.columns] * x.var

# plot result
grid::grid.draw(gp)

这篇关于如何自动调整facet_wrap的每个构面的宽度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆