代码之家  ›  专栏  ›  技术社区  ›  stackinator Brenton Wiernik

ggplot2更改每个面面板的轴限制

  •  1
  • stackinator Brenton Wiernik  · 技术社区  · 7 年前
    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 或者两者的某种组合。

    3 回复  |  直到 7 年前
        1
  •  1
  •   Ben Bolker    7 年前

    准备工作

    为每个面的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)
    ## 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
  •  2
  •   Uwe    7 年前

    这是一个长期存在的功能请求(请参见,例如, 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))
    

    enter image description here

    如果每个方面的参数存储在数据帧中 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()
    
        3
  •  0
  •   Johanna    7 年前

    我想用一个带有刻面刻度的对数刻度,然后挣扎。

    结果我必须在两个位置指定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()