Как я могу проверить, имеет ли график фиксированное соотношение сторон в R - PullRequest
3 голосов
/ 06 ноября 2019

Интересно, есть ли способ спросить 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

Есть ли способ сделать это?

Ответы [ 5 ]

3 голосов
/ 06 ноября 2019

Предположим, у нас есть следующие графики:

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
2 голосов
/ 07 ноября 2019

Ответы, которые запрашивают тему, ненадежны, потому что график может иметь фиксированное соотношение сторон просто потому, что его делает координата, независимо от настроек темы. Например, любые графики, основанные на geom_sf(), будут иметь фиксированное соотношение сторон. Правильный способ сделать это - запросить гроб, сгенерированный ggplot.

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
2 голосов
/ 06 ноября 2019

Действительно хороший способ решения таких проблем - использовать map из пакета purrr. При этом вам не придется искать в списке вручную:

is_fixed_ratio <- function(plot){
  purrr::map(plot, "aspect.ratio") %>% 
    unlist() %>% 
    is.null() %>% 
    !.
}
is_fixed_ratio(plot_a)
is_fixed_ratio(plot_b)
2 голосов
/ 06 ноября 2019

Отредактировано для проверки любого соотношения сторон

> !is.null(plot_a$theme$aspect.ratio)
[1] TRUE
> !is.null(plot_b$theme$aspect.ratio)
[1] FALSE
0 голосов
/ 06 ноября 2019

Я не уверен насчет функции, но есть «быстрый и грязный» способ проверить это. если развернуть подокно графиков, график без фиксированного соотношения сторон будет растягиваться и расширяться, а график с фиксированным соотношением останется с той же шириной.

Вы также можете указать масштаб, ширину и высотуграфик непосредственно с помощью ggsave, например,

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

Не могли бы вы указать, как бы вы хотели проверить свои графики?

...