当最后一行的面板少于列时,xyplot 底轴
xyplot bottom axis when last row has fewer panels than columns
考虑具有 relation='fixed'
、alternating=FALSE
和 as.table=TRUE
的晶格 xyplot
。
如果面板的最后一行不完整(即面板的数量少于布局的列数),则不会绘制 x 轴。例如,下图中的面板 4 没有 x 轴 ticks/labels.
library(lattice)
d <- data.frame(x=runif(100), y=runif(100), grp=gl(5, 20))
xyplot(y~x|grp, d, as.table=TRUE, scales=list(alternating=FALSE, tck=c(1, 0)))
如何添加该轴?
理想情况下,我只希望底部和左侧有轴,底部不完整的面板行(与使用 as.table=FALSE
时不同,它在顶部绘制不完整的行)。对于上面的示例,我希望轴绘制在面板 4 的底部边框上,而不是与面板 5 的 x 轴一致。
我知道这很容易解决,例如,使用基本图形方法。我对晶格解决方案特别感兴趣。
我不是晶格专家,但我相信这可能有用。这个想法最初发布于 here。首先,我将重新生成示例:
library(lattice)
set.seed(1)
d <- data.frame(x=runif(100), y=runif(100), grp=gl(5, 20))
接下来,让我们定义一个函数来控制 面板 设置:
trellis.par.set(clip = list(panel = "off"))
myPan <- function(...){
panel.xyplot(...)
if(panel.number() == 4) {
at = seq(0,1,by = 0.2)
panel.axis("bottom", at = at, outside = T,
labels = T, half = F)
}
if(panel.number() == 5) {
at = seq(0,1,by = 0.2)
panel.axis("bottom",at = at, outside = T,
labels = T, half = F)
}
}
现在进入剧情:
xyplot(y~x|grp, d, as.table=TRUE,
scales = list(
x = list(draw = F, relation="same"),
y = list(tck=c(1,0), alternating=F)),
layout = c(2,3),
panel = myPan)
可以看出,在xyplot
命令中我们要求不绘制x轴(draw = F
)但是后来面板调用了myPan
函数。我们特别要求为面板 4 和 5 绘制 x-axis。
产出
希望能给大家一些改进的方向。
这是另一种基于 @user20650 的(现已删除)答案中提供的代码的方法。它直接使用 grid
,专注于缺少轴(或至少 假定 缺少轴)的活动网格图面板,并添加它们。我们还假设 x-scale 是固定的。
函数(也作为要点 here 存在):
add_axes <- function() {
library(grid)
library(lattice)
l <- trellis.currentLayout()
pan <- which(l[nrow(l), ]==0)
if(length(pan) > 0) {
g <- grid.ls(print=FALSE)
# use an existing panel as a template for ticks
ticks <- grid.get(g$name[grep("ticks.bottom.panel", g$name)][[1]])
# use an existing panel as a template for labels
labels <- grid.get(g$name[grep("ticklabels.bottom.panel", g$name)][[1]])
ax <- grobTree(ticks, labels)
invisible(sapply(pan, function(x) {
trellis.focus("panel", x, nrow(l)-1, clip.off=TRUE)
grid.draw(ax)
trellis.unfocus()
}))
}
}
一个例子:
library(lattice)
d <- data.frame(x=runif(100), y=runif(100), grp=gl(5, 20))
xyplot(y~x|grp, d, as.table=TRUE, scales=list(tck=c(1,0), alternating=FALSE),
layout=c(4, 2), xlim=c(-0.1, 1.1))
add_axes()
考虑具有 relation='fixed'
、alternating=FALSE
和 as.table=TRUE
的晶格 xyplot
。
如果面板的最后一行不完整(即面板的数量少于布局的列数),则不会绘制 x 轴。例如,下图中的面板 4 没有 x 轴 ticks/labels.
library(lattice)
d <- data.frame(x=runif(100), y=runif(100), grp=gl(5, 20))
xyplot(y~x|grp, d, as.table=TRUE, scales=list(alternating=FALSE, tck=c(1, 0)))
如何添加该轴?
理想情况下,我只希望底部和左侧有轴,底部不完整的面板行(与使用 as.table=FALSE
时不同,它在顶部绘制不完整的行)。对于上面的示例,我希望轴绘制在面板 4 的底部边框上,而不是与面板 5 的 x 轴一致。
我知道这很容易解决,例如,使用基本图形方法。我对晶格解决方案特别感兴趣。
我不是晶格专家,但我相信这可能有用。这个想法最初发布于 here。首先,我将重新生成示例:
library(lattice)
set.seed(1)
d <- data.frame(x=runif(100), y=runif(100), grp=gl(5, 20))
接下来,让我们定义一个函数来控制 面板 设置:
trellis.par.set(clip = list(panel = "off"))
myPan <- function(...){
panel.xyplot(...)
if(panel.number() == 4) {
at = seq(0,1,by = 0.2)
panel.axis("bottom", at = at, outside = T,
labels = T, half = F)
}
if(panel.number() == 5) {
at = seq(0,1,by = 0.2)
panel.axis("bottom",at = at, outside = T,
labels = T, half = F)
}
}
现在进入剧情:
xyplot(y~x|grp, d, as.table=TRUE,
scales = list(
x = list(draw = F, relation="same"),
y = list(tck=c(1,0), alternating=F)),
layout = c(2,3),
panel = myPan)
可以看出,在xyplot
命令中我们要求不绘制x轴(draw = F
)但是后来面板调用了myPan
函数。我们特别要求为面板 4 和 5 绘制 x-axis。
产出
希望能给大家一些改进的方向。
这是另一种基于 @user20650 的(现已删除)答案中提供的代码的方法。它直接使用 grid
,专注于缺少轴(或至少 假定 缺少轴)的活动网格图面板,并添加它们。我们还假设 x-scale 是固定的。
函数(也作为要点 here 存在):
add_axes <- function() {
library(grid)
library(lattice)
l <- trellis.currentLayout()
pan <- which(l[nrow(l), ]==0)
if(length(pan) > 0) {
g <- grid.ls(print=FALSE)
# use an existing panel as a template for ticks
ticks <- grid.get(g$name[grep("ticks.bottom.panel", g$name)][[1]])
# use an existing panel as a template for labels
labels <- grid.get(g$name[grep("ticklabels.bottom.panel", g$name)][[1]])
ax <- grobTree(ticks, labels)
invisible(sapply(pan, function(x) {
trellis.focus("panel", x, nrow(l)-1, clip.off=TRUE)
grid.draw(ax)
trellis.unfocus()
}))
}
}
一个例子:
library(lattice)
d <- data.frame(x=runif(100), y=runif(100), grp=gl(5, 20))
xyplot(y~x|grp, d, as.table=TRUE, scales=list(tck=c(1,0), alternating=FALSE),
layout=c(4, 2), xlim=c(-0.1, 1.1))
add_axes()