【问题标题】:How can I test whether a plot has a fixed aspect ratio in R如何测试绘图在 R 中是否具有固定的纵横比
【发布时间】:2019-11-07 05:01:39
【问题描述】:

我想知道是否有办法询问 R 情节是否有固定的纵横比。以下是两个示例图:

library (ggplot2)

plot_a <- ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) +
          geom_point()+
          theme (aspect.ratio = 1)

plot_b <- ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) +
          geom_point()

plot_a 有固定的纵横比,plot_b 没有固定的纵横比。我正在寻找以下虚函数:

is_fixed_ratio (plot_a) 
TRUE

is_fixed_ratio (plot_b)
FALSE

有没有办法做到这一点?

【问题讨论】:

    标签: r ggplot2 aspect-ratio


    【解决方案1】:

    假设我们有以下图:

    library (ggplot2)
    
    plot_a <- ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) +
              geom_point()+
              theme (aspect.ratio = 1)
    
    plot_b <- ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) +
              geom_point()
    
    plot_c <- ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) +
              geom_point() +
              coord_equal()
    

    当前接受的答案将按如下方式处理:

    is_fixed_ratio <- function(plot){
      purrr::map(plot, "aspect.ratio") %>% 
        unlist() %>% 
        is.null() %>% 
        !.
    }
    
    > is_fixed_ratio(plot_a)
    [1] TRUE
    > is_fixed_ratio(plot_b)
    [1] FALSE
    > is_fixed_ratio(plot_c)
    [1] FALSE
    

    plot_c 确实有一个固定的纵横比,只是没有通过主题指定。

    要检查这一点,您可以检查绘图的 gtable:

    is_fixed_ratio2 <- function(plot) {
      ggplotGrob(plot)$respect
    }
    
    > is_fixed_ratio2(plot_a)
    [1] TRUE
    > is_fixed_ratio2(plot_b)
    [1] FALSE
    > is_fixed_ratio2(plot_c)
    [1] TRUE
    

    【讨论】:

    • 这是 IMO 一个比公认的更好的答案,而且未来可能不太可能改变。
    • 在基本上发布了the same.之后才注意到这个答案
    • 很高兴知道至少它是正确的,但我想说的是你的解释更准确。
    【解决方案2】:

    处理此类问题的一个非常好的方法是使用来自purrr 包的map。有了这个,您不必手动在列表中搜索:

    is_fixed_ratio <- function(plot){
      purrr::map(plot, "aspect.ratio") %>% 
        unlist() %>% 
        is.null() %>% 
        !.
    }
    is_fixed_ratio(plot_a)
    is_fixed_ratio(plot_b)
    

    【讨论】:

    • 这确实是一个很好的选择。由于人类可读性,我确实喜欢通过专用函数进行测试的想法。
    【解决方案3】:

    编辑以检查任何纵横比

    > !is.null(plot_a$theme$aspect.ratio)
    [1] TRUE
    > !is.null(plot_b$theme$aspect.ratio)
    [1] FALSE
    

    【讨论】:

    • 好的,如果aspect.ratio 正好是 1,这可以正常工作。但是,如果有一个固定的纵横比偏离 1,isTRUE(the_plot$theme$aspect.ratio == 1) 它会返回 FALSE,我想(我只想测试 if 有一个固定的纵横比)。我可以尝试一个相当小的值,在大多数情况下,我想:isTRUE(the_plot$theme$aspect.ratio &gt;= .0001)
    • 测试是否存在纵横比同样简单。只需要检查 aspect.ratio 列表元素是否存在。
    • 这就是解决方案。谢谢!
    【解决方案4】:

    查询主题的答案并不可靠,因为无论主题设置如何,情节都可以具有固定的纵横比,仅仅是因为坐标使它如此。例如,任何基于geom_sf() 的绘图都将具有固定的纵横比。正确的做法是查询 ggplot 生成的 grob。

    library(tidyverse)
    
    p_var <- ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
      geom_point()
    
    p_fixed <- p_var + coord_fixed()
    
    
    # correct approach: query the grob
    is_fixed_ratio <- function(plot) {
      g <- ggplotGrob(plot)
      isTRUE(g$respect)
    }
    
    # should return false
    is_fixed_ratio(p_var)
    #> [1] FALSE
    
    # should return true
    is_fixed_ratio(p_fixed)
    #> [1] TRUE
    

    相比之下,如果我们尝试不正确的方法,事情就不会按预期工作。

    # incorrect approach: rely on a theme setting
    is_fixed_ratio_wrong <- function(plot) {
      purrr::map(plot, "aspect.ratio") %>% 
        unlist() %>% 
        is.null() %>% 
        !.
    }
    
    # should return false, and does so
    is_fixed_ratio_wrong(p_var)
    #> [1] FALSE
    
    # should return true, but doesn't
    is_fixed_ratio_wrong(p_fixed)
    #> [1] FALSE
    

    这也适用于问题中给出的示例:

    plot_a <- ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) +
      geom_point()+
      theme(aspect.ratio = 1)
    
    plot_b <- ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) +
      geom_point()
    
    is_fixed_ratio(plot_a)
    #> [1] TRUE
    
    is_fixed_ratio(plot_b)
    #> [1] FALSE
    

    再举一个例子:

    nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
    p <- ggplot(nc) +
      geom_sf(aes(fill = AREA))
    
    is_fixed_ratio(p)
    #> [1] TRUE
    
    is_fixed_ratio_wrong(p)
    #> [1] FALSE
    

    【讨论】:

      【解决方案5】:

      我不确定功能,但有一种“快速而肮脏”的方法来检查它。如果您展开绘图子窗口,没有固定纵横比的绘图将拉伸和扩展,而具有固定比例的绘图将保持相同的宽度。

      您也可以直接使用 ggsave 指定绘图的比例、宽度和高度,例如

      ggsave("figure.png", plot = last_plot(),
         scale = 1, width = 20, height = 15, units = "cm",
         dpi = 300)
      

      您能否具体说明您希望如何检查您的地块?

      【讨论】:

      • 我知道 :) 但是,我需要 R 来“知道”一个情节是否有固定的aspect.ratio,因为我想在更大的功能。
      猜你喜欢
      • 1970-01-01
      • 2018-11-10
      • 2011-10-26
      • 2013-10-31
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多