Reputation: 5456
I can't fix the colors of my heat-maps according to their values. Same values should have same colors. The goal is to keep all values below a certain threshold (0.05) in (constant) gray. For values greather than this threshold, the colors should gradually change from "firebrick1" to "firebrick4".
For example, "Plant 5"/"202004" = 70.6 is red if I use variable utilization2
and gray if I use variable utilization
. How can I fix that?
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)
Upvotes: 2
Views: 445
Reputation: 8117
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)
The point is that scale_fill_gradientn()
sets the limits of the scale to max and min of the vector of interest. You have to set them manually. In this case I chose both the max and min of both columns (limits = c(min(d$utilization, d$utilization2), max(d$utilization, d$utilization2))
).
Upvotes: 2
Reputation: 37933
The colours are interpolated between the values, so a trick you could do is is to set both 0
and 0.05
as gray, and begin the next colour at a very small increment to 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)
Maybe this is not necessary to mention, but the fill scale rescales all fill values to a range between 0-1 depending on the limits (see ?scales::rescale
), so the 0.05
you put in the values
argument is the bottom 5% of the range value and not unscaled data values in utilization
that are below 0.05. If you want to have consistent fill scales over multiple plots, you'd have to set the limits
argument manually.
Upvotes: 1