前置条件
定义原始图形并确定每个面的y轴所需参数:
library(ggplot2)
g0 <- ggplot(mpg, aes(displ, cty)) +
geom_point() +
facet_grid(rows = vars(drv), scales = "free")
facet_bounds <- read.table(header=TRUE,
text=
"drv ymin ymax breaks
4 5 25 5
f 0 40 10
r 10 20 2",
stringsAsFactors=FALSE)
版本1:放入虚假数据点
这不符合breaks
规格,但它能正确获取边界:
定义一个新的数据框,其中包括每个drv
的最小/最大值:
ff <- with(facet_bounds,
data.frame(cty=c(ymin,ymax),
drv=c(drv,drv)))
将它们添加到图表中(由于x
是NA
,所以它们不会被绘制,但仍然用于定义比例尺)
g0 + geom_point(data=ff,x=NA)
这与expand_limits()
的功能类似,不同的是该函数适用于“所有面板或所有图形”。
版本2:检测您所在的面板
这很丑陋,并取决于每个组具有唯一范围。
library(dplyr)
lims <- (mpg
%>% group_by(drv)
%>% summarise(ymin=min(cty),ymax=max(cty))
)
休息函数:找出与给定限制集对应的组...
bfun <- function(limits) {
grp <- which(lims$ymin==limits[1] & lims$ymax==limits[2])
bb <- facet_bounds[grp,]
pp <- pretty(c(bb$ymin,bb$ymax),n=bb$breaks)
return(pp)
}
g0 + scale_y_continuous(breaks=bfun, expand=expand_scale(0,0))
这里的另一个问题是我们不得不设置expand_scale(0,0)
,以使限制与组限制完全相等,而这可能不是您想要的绘图方式...
如果breaks()
函数能够以某种方式传递有关当前正在计算哪个面板的信息,那就太好了...
scale_y_continuous
或coord_cartesian
)都不适用于面板。如果这些是数据比例的扩展,我也通过向数据集添加虚假数据并确保在定义比例时考虑它们但不绘制它们来完成了这个过程。还可以使用breaks()
函数来进行hack,通过检测当前正在考虑哪个子图... - Ben Bolkerggplot2
内置的数据集mpg
。 - Calum Youscale_y_continuous(breaks=my_breaks,expand=expand_scale(mult=c(0,.1)))
来解决,其中my_break
函数设置了断点,而expand_scale
则设置了限制。 - pengchy