library(tidyverse)
ggplot(mpg, aes(displ, cty)) +
geom_point() +
facet_grid(rows = vars(drv), scales = "free")
上面的ggplot代码由三个面板4
,f
和r
组成。我希望每个面板的y轴限制如下:
Panel y-min y-max breaks
----- ----- ----- ------
4 5 25 5
f 0 40 10
r 10 20 2
如何修改我的代码以完成此操作?不确定scale_y_continuous
是否更有意义,还是coord_cartesian
还是两者的某种组合。
答案 0 :(得分:2)
这是一个长期存在的功能请求(例如,参见2009,2011,2016),由单独的软件包facetscales
处理。
devtools::install_github("zeehio/facetscales")
library(g)
library(facetscales)
scales_y <- list(
`4` = scale_y_continuous(limits = c(5, 25), breaks = seq(5, 25, 5)),
`f` = scale_y_continuous(limits = c(0, 40), breaks = seq(0, 40, 10)),
`r` = scale_y_continuous(limits = c(10, 20), breaks = seq(10, 20, 2))
)
ggplot(mpg, aes(displ, cty)) +
geom_point() +
facet_grid_sc(rows = vars(drv), scales = list(y = scales_y))
如果每个方面的参数都存储在数据帧facet_params
中,我们可以根据语言进行计算以创建scale_y
:
library(tidyverse)
facet_params <- read_table("drv y_min y_max breaks
4 5 25 5
f 0 40 10
r 10 20 2")
scales_y <- facet_params %>%
str_glue_data(
"`{drv}` = scale_y_continuous(limits = c({y_min}, {y_max}), ",
"breaks = seq({y_min}, {y_max}, {breaks}))") %>%
str_flatten(", ") %>%
str_c("list(", ., ")") %>%
parse(text = .) %>%
eval()
答案 1 :(得分:1)
为每个构面的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)
这不符合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()
的操作类似,不同之处在于该功能“适用于所有面板或所有图”。
这很丑陋,取决于每个组都有一个唯一的范围。
library(dplyr)
## compute limits for each group
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()
函数的信息,那么有关当前正在计算哪个面板的信息...
答案 2 :(得分:0)
我想使用带有刻面刻度的对数刻度并且很费力。
原来,我必须在两个位置指定log10:
scales_x <- list(
"B" = scale_x_log10(limits=c(0.1, 10), breaks=c(0.1, 1, 10)),
"C" = scale_x_log10(limits=c(0.008, 1), breaks=c(0.01, 0.1, 1)),
"E" = scale_x_log10(limits=c(0.01, 1), breaks=c(0.01, 0.1, 1)),
"R" = scale_x_log10(limits=c(0.01, 1), breaks=c(0.01, 0.1, 1))
)
并在情节中
ggplot(...) + facet_grid_sc(...) + scale_x_log10()