我和this用户有同样的问题——我有一个"锯齿状"平面图,其中底行的面板比其他行少,我希望在每列的底部有x轴记号.

解决这个问题的建议方案是设置scales="free_x".(在ggplot 0.9.2.1中,我认为我正在寻找的行为在早期版本中是默认的.)在我的例子中,这是一个糟糕的解决方案:我的实际轴标签将相当长,因此将它们放在每行下面将占用太多空间.结果如下:

 x <- gl(3, 1, 15, labels=paste("this is a very long axis label ", letters[1:5]))
 y <- rnorm(length(x))
 l <- gl(5, 3, 15)
 d <- data.frame(x=x, y=y, l=l)
 ggplot(d, aes(x=x, y=y)) + geom_point() + facet_wrap(~l, scales="free_x") + 
   theme(axis.text.x=element_text(angle=90, hjust=1))

在此处输入图像描述

在 comments here中,安德里建议可以在grid中手动完成,但我不知道如何开始.

推荐答案

如果我没记错的话,关于如何将所有标签添加到最后一列下的同一行,以及如何将这些最后的标签提升到下一行,都有问题.下面是两种情况下的函数:

Edit:因为这就像是print.ggplot的替代品(见getAnywhere(print.ggplot)),所以我添加了一些行来保留功能.

Edit 2:我对它做了更多的改进:不再需要指定nrowncol,所有面板的绘图也可以打印.

library(grid)
# pos - where to add new labels
# newpage, vp - see ?print.ggplot
facetAdjust <- function(x, pos = c("up", "down"), 
                        newpage = is.null(vp), vp = NULL)
{
  # part of print.ggplot
  ggplot2:::set_last_plot(x)
  if(newpage)
    grid.newpage()
  pos <- match.arg(pos)
  p <- ggplot_build(x)
  gtable <- ggplot_gtable(p)
  # finding dimensions
  dims <- apply(p$panel$layout[2:3], 2, max)
  nrow <- dims[1]
  ncol <- dims[2]
  # number of panels in the plot
  panels <- sum(grepl("panel", names(gtable$grobs)))
  space <- ncol * nrow
  # missing panels
  n <- space - panels
  # checking whether modifications are needed
  if(panels != space){
    # indices of panels to fix
    idx <- (space - ncol - n + 1):(space - ncol)
    # copying x-axis of the last existing panel to the chosen panels 
    # in the row above
    gtable$grobs[paste0("axis_b",idx)] <- list(gtable$grobs[[paste0("axis_b",panels)]])
    if(pos == "down"){
      # if pos == down then shifting labels down to the same level as 
      # the x-axis of last panel
      rows <- grep(paste0("axis_b\\-[", idx[1], "-", idx[n], "]"), 
                   gtable$layout$name)
      lastAxis <- grep(paste0("axis_b\\-", panels), gtable$layout$name)
      gtable$layout[rows, c("t","b")] <- gtable$layout[lastAxis, c("t")]
    }
  }
  # again part of print.ggplot, plotting adjusted version
  if(is.null(vp)){
    grid.draw(gtable)
  }
  else{
    if (is.character(vp)) 
      seekViewport(vp)
    else pushViewport(vp)
    grid.draw(gtable)
    upViewport()
  }
  invisible(p)
}

下面是它的外观

d <- ggplot(diamonds, aes(carat, price, fill = ..density..)) +
  xlim(0, 2) + stat_binhex(na.rm = TRUE) + theme(aspect.ratio = 1) + 
  facet_wrap(~ color)
facetAdjust(d)

在此处输入图像描述

facetAdjust(d, "down")

在此处输入图像描述

Edit 3:

这是一个替代方案,上面的方案也可以.

如果要将ggsavefacetAdjust结合使用,会出现一些问题.ggplot类的绘图是必需的,因为源代码中有两部分:print(plot)default_name(plot),以防其中一部分无法手动提供文件名(根据?ggsave,似乎它不应该工作).因此,给定一个文件名,有一个解决方法(在某些情况下可能有副作用):

首先,让我们考虑实现浮动轴主要作用的分离函数.通常,它会返回gtable个对象,但我们使用class(gtable) <- c("facetAdjust", "gtable", "ggplot").这样,可以根据需要使用ggsaveprint(plot)个工程(print.facetAdjust见下文)

facetAdjust <- function(x, pos = c("up", "down"))
{
  pos <- match.arg(pos)
  p <- ggplot_build(x)
  gtable <- ggplot_gtable(p); dev.off()
  dims <- apply(p$panel$layout[2:3], 2, max)
  nrow <- dims[1]
  ncol <- dims[2]
  panels <- sum(grepl("panel", names(gtable$grobs)))
  space <- ncol * nrow
  n <- space - panels
  if(panels != space){
    idx <- (space - ncol - n + 1):(space - ncol)
    gtable$grobs[paste0("axis_b",idx)] <- list(gtable$grobs[[paste0("axis_b",panels)]])
    if(pos == "down"){
      rows <- grep(paste0("axis_b\\-[", idx[1], "-", idx[n], "]"), 
                   gtable$layout$name)
      lastAxis <- grep(paste0("axis_b\\-", panels), gtable$layout$name)
      gtable$layout[rows, c("t","b")] <- gtable$layout[lastAxis, c("t")]
    }
  }
  class(gtable) <- c("facetAdjust", "gtable", "ggplot"); gtable
}

打印功能仅与ggplot2:::print.ggplot不同几行:

print.facetAdjust <- function(x, newpage = is.null(vp), vp = NULL) {
  if(newpage)
    grid.newpage()
  if(is.null(vp)){
    grid.draw(x)
  } else {
    if (is.character(vp)) 
      seekViewport(vp)
    else pushViewport(vp)
    grid.draw(x)
    upViewport()
  }
  invisible(x)
}

例子:

d <- ggplot(diamonds, aes(carat, price, fill = ..density..)) +
  xlim(0, 2) + stat_binhex(na.rm = TRUE) + theme(aspect.ratio = 1) + 
  facet_wrap(~ color)
p <- facetAdjust(d) # No output
print(p) # The same output as with the old version of facetAdjust()
ggsave("name.pdf", p) # Works, a filename is necessary

R相关问答推荐

在之前合并的数据.tables中分配新列后.internal.selfref无效

如何在球体上绘制轮廓线?

如何以编程方式将X轴勾号上的希腊符号合并到R图中?

R中的枢轴/转置

r中的stat_difference函数不起作用

如何在R中合并和合并多个rabrame?

R for循环返回到先前值

将数据集中的值增加到当前包含的最大值

在GGPLATE中将突出的点放在前面

如何改变x轴比例的列在面

为什么当用osmdata映射R时会得到相邻状态?

使用外部文件分配变量名及其值

如何使用tryCatch执行语句并忽略警告?

R如何将列名转换为更好的年和月格式

在ggplot2上从多个数据框创建复杂的自定义图形

R预测包如何处理ARIMA(Auto.arima函数)中的缺失值

ggplot斜体轴刻度标签中的单个字符-以前的帖子建议不工作

按组使用dummy r获取高于标准的行的平均值

如何使用ggplot2根据绘图中生成的斜率对小平面进行排序?

R-如何在ggplot2中显示具有不同x轴值(日期)的多行?