Неправильный градиент цвета при использовании ковпота для совмещения участков - PullRequest
4 голосов
/ 17 апреля 2019

Скажем, у меня есть набор данных со значениями x и y, которые сгруппированы по двум переменным: grp равно a, b или c, а subgrp равно E, F или G.

  • a имеет y значения в [0, 1]
  • b имеет y значения в [10, 11]
  • c имеет значения y в [100, 101].

Я бы хотел построить y против x с цветом точки, определенной y для всех комбинаций grp и subgrp. Поскольку каждый grp имеет очень разные значения y, я не могу просто использовать facet_grid, так как цветовые шкалы были бы бесполезны. Итак, я строю каждый grp со своим собственным масштабом, затем соединяю их вместе с plot_grid из cowplot. Я также хочу использовать трехточечный градиент, заданный scale_colour_gradient2. Мой код выглядит так:

# Set RNG seed
set.seed(42)

# Toy data frame
df <- data.frame(x = runif(270), y = runif(270) + rep(c(0, 10, 100), each = 90),
                 grp = rep(letters[1:3], each = 90), subgrp = rep(LETTERS[4:6], 90))

head(df)
#>           x         y grp subgrp
#> 1 0.9148060 0.1362958   a      D
#> 2 0.9370754 0.7853494   a      E
#> 3 0.2861395 0.4533034   a      F
#> 4 0.8304476 0.1357424   a      D
#> 5 0.6417455 0.8852210   a      E
#> 6 0.5190959 0.3367135   a      F

# Load libraries
library(cowplot)
library(ggplot2)
library(dplyr)

# Plotting list
g_list <- list()

# Loop through groups 'grp'
for(i in levels(df$grp)){
  # Subset the data
  df_subset <- df %>% filter(grp == i)

  # Calculate the midpoint
  mp <- mean(df_subset$y)

  # Print midpoint
  message("Midpoint: ", mp)

  g <- ggplot(df_subset) + geom_point(aes(x = x, y = y, colour = y))
  g <- g + facet_grid(. ~ subgrp) + ggtitle(i)
  g <- g + scale_colour_gradient2(low = "blue", high = "red", mid = "yellow", midpoint = mp)
  g_list[[i]] <- g
}
#> Midpoint: 0.460748857570191
#> Midpoint: 10.4696476330981
#> Midpoint: 100.471083269571

plot_grid(plotlist = g_list, ncol = 1)

Создано в 2019-04-17 пакетом Представить (v0.2.1)

В этом коде я указываю среднюю точку цветового градиента как среднее значение y для каждого grp. Я печатаю это и проверяю, что это правильно. Это.

Мой вопрос: почему мои цветовые шкалы неверны для первых двух графиков?

Похоже, один и тот же диапазон применяется к каждому grp несмотря на подмножество данных Если я заменим for(i in levels(df$grp)){ на for(i in levels(df$grp)[1]){, цветовая шкала будет верна для одного создаваемого графика.


Обновление

Хорошо, это странно. Вставка ggplot_build(g)$data[[1]]$colour непосредственно перед тем, как g_list[[i]] <- g решит проблему. Но почему?

enter image description here

1 Ответ

2 голосов
/ 17 апреля 2019

Короче говоря, вы создаете неоцененные обещания, а затем оцениваете их в тот момент, когда исходные данные исчезают. Этой проблемы обычно избегают, если вы используете правильный функциональный стиль программирования, а не процедурный код. То есть, определите функцию, которая выполняет эту работу, а затем используйте функцию apply для цикла.

set.seed(42)

# Toy data frame
df <- data.frame(x = runif(270), y = runif(270) + rep(c(0, 10, 100), each = 90),
                 grp = rep(letters[1:3], each = 90), subgrp = rep(LETTERS[4:6], 90))

library(cowplot)
library(ggplot2)
library(dplyr)

# Loop through groups 'grp'
g_list <- lapply(
  levels(df$grp), 
  function(i) {
    # Subset the data
    df_subset <- df %>% filter(grp == i)

    # Calculate the midpoint
    mp <- mean(df_subset$y)

    # Print midpoint
    message("Midpoint: ", mp)

    g <- ggplot(df_subset) + geom_point(aes(x = x, y = y, colour = y))
    g <- g + facet_grid(. ~ subgrp) + ggtitle(i)
    g <- g + scale_colour_gradient2(low = "blue", high = "red", mid = "yellow", midpoint = mp)
    g
  }
)
#> Midpoint: 0.460748857570191
#> Midpoint: 10.4696476330981
#> Midpoint: 100.471083269571

plot_grid(plotlist = g_list, ncol = 1)

Создано в 2019-04-17 пакетом Представления (v0.2.1)

...