grid.layout不喜欢尊重和复合单位
使用unit.pmax
作为unit.pmax
中宽度/高度的默认比较比我希望的要难得多; 经过几个小时的头部划伤,我缩小了这种情况:
library(grid)
w <- list(unit(1,"null"), unit(1,"null"))
class(w) <- c("unit.list", "unit")
h <- unit(1, "in")
gl1 <- grid.layout(1, 2, widths = w, heights = h,
respect = TRUE)
grid.newpage()
grid.show.layout(gl1) # fine
w2 <- w
w2[[1]] <- unit.pmax(unit(1,"null"), unit(1,"null"))
gl2 <- grid.layout(1, 2, widths = w2, heights = h,
respect = FALSE)
grid.newpage()
grid.show.layout(gl2)# fine
gl3 <- grid.layout(1, 2, widths = w2, heights = h,
respect = TRUE)
grid.newpage()
grid.show.layout(gl3)
## Error in grid.Call.graphics(L_setviewport, vp, TRUE) :
## non-finite location and/or size for viewport
所以unit.pmax(unit(1,"null"), unit(1,"null"))
和respect = TRUE
使网格抱怨。 如果你想知道,这种情况会出现在ggplot2 with facet_grid
和theme(aspect.ratio = ...)
。
我可以隐约unit.pmax()
在尝试使用respect
参数之前, unit.pmax()
应该简化null单位,但我并不真正知道这一切意味着什么。 但实际上,它阻止了我改进gtable的cbind / rbind。
任何解决方法?
编辑:我不知道如何提供一个最小的例子与ggplot2
,除了安装我的叉子和运行
ggplot(data.frame(x=1:8, y=1:8, f=gl(2,4)), aes(x, y)) +
geom_point() +
facet_grid(f~.) +
theme(aspect.ratio=3)
# Error in grid.Call.graphics(L_setviewport, vp, TRUE) :
# non-finite location and/or size for viewport
所以在这种情况下unit.pmax()
失败,而当前比较方法compare.unit(,,pmax)
在其他情况下失败,例如,
p1 = qplot(1, 1); p2 = qplot(1,1)
cbind(ggplotGrob(p1), ggplotGrob(p2), size="max")
# Error in mmm < each : comparison of these types is not implemented
这不是最优的,但如果其他所有的都失败了,你可以重写unit.pmax
来使它做你想做的事情。
下面的函数就像unit.pmax()
一样unit.pmax()
除了每当要求查找两个或更多个单位对象的最大值时,所有都以"null"
单位,它返回它们的值“最大”,而不是表达式形式为max(x,y,...)
。 (有关示例,请参阅下面的第二个代码块。)
unit.pmax2 <-
function (...)
{
select.i <- function(unit, i) {
unit[i, top = FALSE]
}
x <- list(...)
numargs <- length(x)
if (numargs == 0L)
stop("no arguments where at least one expected")
maxlength <- 0L
for (i in seq_len(numargs)) if (length(x[[i]]) > maxlength)
maxlength <- length(x[[i]])
## result <- max(unit.list.from.list(lapply(x, select.i, 1L)))
UL <- grid:::unit.list.from.list(lapply(x, select.i, 1L)) ##
result <- if(all(sapply(UL, attr, "unit")=="null")) { ##
UL[which.max(UL)]} else {max(UL)} ##
if (maxlength > 1L)
for (i in 2L:maxlength) {
## result <- unit.c(result, max(unit.list.from.list(lapply(x,
## select.i, i))))
UL <- grid:::unit.list.from.list(lapply(x, select.i, i)) ##
temp <- if(all(sapply(UL, attr, "unit")=="null")) { ##
UL[which.max(UL)]} else {max(UL)} ##
result <- unit.c(result, temp) ##
}
result
}
要查看unit.pmax()
和unit.pmax2()
之间的差异,请比较:
A <- list(unit(1,"null"), unit(1,"null"), unit(1,"null"))
B <- list(unit(1,"null"), unit(4,"null"), unit(1,"null"))
C <- list(unit(1,"null"), unit(2,"null"), unit(1,"inch"))
class(A) <- class(B) <- class(C) <- c("unit.list", "unit")
unit.pmax(A, B, C)
# [1] max(1null, 1null, 1null) max(1null, 4null, 2null) max(1null, 1null, 1inch)
unit.pmax2(A, B, C)
# [1] 1null 4null max(1null, 1null, 1inch)
测试它显示它的工作。 (请注意,您还需要将w2[[1]] <- ...
替换为w2[1] <- ...
以避免当respect = TRUE
时发生投诉。)
library(grid)
w2 <- list(unit(1,"null"), unit(1,"null"))
class(w2) <- c("unit.list", "unit")
h <- unit(1, "in")
w2[1] <- unit.pmax2(unit(1,"null"), unit(1,"null"))
## w2[[1]] <- unit.pmax(unit(1,"null"), unit(1,"null")) ## For comparison
gl3 <- grid.layout(1, 2, widths = w2, heights = h,
respect = TRUE)
grid.newpage()
grid.show.layout(gl3)
Paul Murrell在R-devel @ r65845的修复似乎解决了这个问题。 不幸的是,这意味着gtable
的更新至少要等到下一个R版本发布(可能要更长一些,因为ggplot2 dev通常采用保守的方式来支持旧版本)。