Как исправить непрерывную цветовую гамму ggplot - PullRequest
2 голосов
/ 24 января 2020

Я не могу исправить цвета моих тепловых карт в соответствии с их значениями. Одинаковые значения должны иметь одинаковые цвета. Цель состоит в том, чтобы все значения были ниже определенного порога (0,05) в (постоянном) сером цвете. Для значений, превышающих этот порог, цвета должны постепенно меняться с «firebrick1» на «firebrick4».

Например, «Plant 5» / «202004» = 70,6 - красный, если я использую переменную utilization2 и серый, если я использую переменную utilization. Как я могу это исправить?

library(tidyverse)
library(rlang)

MONTHS <- str_c("2020", sprintf("%02d", 1:12))
PLANTS <- str_c("Plant ", 1:5)

crossing(month = MONTHS, plant = PLANTS) %>%
  mutate(utilization = runif(nrow(.), 70, 100)) %>%
  mutate(utilization2 = if_else(plant == "Plant 2", utilization * 0.67, utilization)) -> d

draw_plot <- function(fill) {
  fill <- ensym(fill)
   d %>%
    ggplot(mapping = aes(x = month, y = plant, fill = !!fill)) +
    geom_tile(aes(width = 0.85, height = 0.85)) +
    geom_text(aes(label = round(!!fill, 1)), color = "white") +
    scale_x_discrete(expand=c(0,0)) +
    scale_y_discrete(expand=c(0,0)) +
    scale_fill_gradientn(colours = c("darkgray", "firebrick1", "firebrick4"), 
                         values = c(0, 0.05, 1)) +
    labs(x = "Month", y = "Production plant", title = str_c("fill = ", fill), color = "Utilization") +
    theme_light() +
    theme(legend.position = "none")
}
draw_plot(utilization)
draw_plot(utilization2)

enter image description here

enter image description here

Ответы [ 2 ]

2 голосов
/ 24 января 2020
library(tidyverse)
library(rlang)

MONTHS <- str_c("2020", sprintf("%02d", 1:12))
PLANTS <- str_c("Plant ", 1:5)

crossing(month = MONTHS, plant = PLANTS) %>%
    mutate(utilization = runif(nrow(.), 70, 100)) %>%
    mutate(utilization2 = if_else(plant == "Plant 2", utilization * 0.67, utilization)) -> d

draw_plot <- function(fill) {
    fill <- ensym(fill)
    d %>%
        ggplot(mapping = aes(x = month, y = plant, fill = !!fill)) +
        geom_tile(aes(width = 0.85, height = 0.85)) +
        geom_text(aes(label = round(!!fill, 1)), color = "white") +
        scale_x_discrete(expand=c(0,0)) +
        scale_y_discrete(expand=c(0,0)) +
        scale_fill_gradientn(colours = c("darkgray", "firebrick1", "firebrick4"),
                             values = c(0, 0.05, 1), limits = c(min(d$utilization, d$utilization2), max(d$utilization, d$utilization2))) +
        labs(x = "Month", y = "Production plant", title = str_c("fill = ", fill), color = "Utilization") +
        scale_color_identity() +
        theme_light() +
        theme(legend.position = "none")
}
draw_plot(utilization)
draw_plot(utilization2)

Дело в том, что scale_fill_gradientn() устанавливает пределы шкалы на максимум и минимум интересующего вектора. Вы должны установить их вручную. В этом случае я выбрал максимальное и минимальное значение для обоих столбцов (limits = c(min(d$utilization, d$utilization2), max(d$utilization, d$utilization2))).

1 голос
/ 24 января 2020

Цвета интерполируются между значениями, поэтому вы могли бы уловить 0 и 0.05 как серый и начать следующий цвет с очень небольшим приращением до 0.05.

draw_plot <- function(fill) {
  fill <- ensym(fill)
  d %>%
    ggplot(mapping = aes(x = month, y = plant, fill = !!fill)) +
    geom_tile(aes(width = 0.85, height = 0.85)) +
    geom_text(aes(label = round(!!fill, 1)), color = "white") +
    scale_x_discrete(expand=c(0,0)) +
    scale_y_discrete(expand=c(0,0)) +
    scale_fill_gradientn(colours = c("darkgray", "darkgray", "firebrick1", "firebrick4"), 
                         values = c(0, 0.05, 0.05 + .Machine$double.eps, 1)) +
    labs(x = "Month", y = "Production plant", title = str_c("fill = ", fill), color = "Utilization") +
    theme_light() +
    theme(legend.position = "none")
}
draw_plot(utilization)
draw_plot(utilization2)

Может быть, об этом нет необходимости упоминать, но шкала заливки изменяет масштаб всех значений заливки в диапазоне от 0 до 1 в зависимости от ограничений (см. ?scales::rescale), поэтому 0.05, который вы вводите в * Аргумент 1009 * - это нижние 5% значения диапазона, а не немасштабированные значения данных в utilization, которые ниже 0,05. Если вы хотите иметь одинаковую шкалу заливки для нескольких графиков, вам придется установить аргумент limits вручную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...