I'm trying to plot different colors for my ratios in a general way (for example case/control)
For example, if we have values between 1 and 0 (which means the value of control is higher), I have a scale from white to blue. But if the value is between 1 and inf, then we have that the case is higher in value and the scale is from white to red.
I'm plotting like this:
mtcars2 <- mtcars
mtcars2$ratio1 <- mtcars$mpg / mtcars$disp
mtcars2$ratio2 <- mtcars$disp / mtcars$mpg
mtcars2$ratio3 <- mtcars$drat / mtcars$wt
a <- max(mtcars2$ratio1)
b <- ifelse(a < 2, 2, a) #so I get a value of b which is above 2 to create the scale in values
ggplot(mtcars, aes(x = rownames(mtcars), y = 1, fill = mtcars2$ratio1))
geom_tile()
theme_minimal()
scale_fill_gradientn(
colours = c("blue", "white", "red"),
na.value = "grey98",
name = "ratio",
values = c(0, 1, b)
)
theme_classic()
theme(axis.text.x = element_text(
size = 10, face = "bold", color = "black",
angle = 45, hjust = 1
)) #b should be always above 1 (I selected 2)
a <- max(mtcars2$ratio2)
b <- ifelse(a < 2, 2, a)
ggplot(mtcars, aes(x = rownames(mtcars), y = 1, fill = mtcars2$ratio2))
geom_tile()
theme_minimal()
scale_fill_gradientn(
colours = c("blue", "white", "red"),
na.value = "grey98",
name = "ratio",
values = c(0, 1, b)
)
theme_classic()
theme(axis.text.x = element_text(
size = 10, face = "bold", color = "black",
angle = 45, hjust = 1
))
a <- max(mtcars2$ratio3)
b <- ifelse(a < 2, 2, a)
ggplot(mtcars, aes(x = rownames(mtcars), y = 1, fill = mtcars2$ratio3))
geom_tile()
theme_minimal()
scale_fill_gradientn(
colours = c("blue", "white", "red"),
na.value = "grey98",
name = "ratio",
values = c(0, 1, b)
)
theme_classic()
theme(axis.text.x = element_text(
size = 10, face = "bold", color = "black",
angle = 45, hjust = 1
))
Which works fine for values between 0 and 1 (when nothing over 1 is present), but does not plot red color for values between 1 and max ratio value and when mixed values are present (between 0 and 1, and 1 and inf)
I can't consider values of log nor normalized values! I need the scale like it is
Using
a = ifelse(max(mtcars2$ratio3) > 1, max(mtcars2$ratio3), 1)
b = ifelse(max(mtcars2$ratio3) > 1, 1/max(mtcars2$ratio3), 1)
c = ifelse(b == 1, 0.99, b)
ggplot(mtcars2, aes(x = rownames(mtcars), y = 1, fill = ratio3))
geom_tile()
theme_minimal()
scale_fill_gradientn(
colours = c("blue", "white", "red"),
na.value = "grey98",
name = "ratio",
limits = c(0, a),
values = c(0, c , 1)
)
theme_classic()
theme(axis.text.x = element_text(
size = 10, face = "bold", color = "black",
angle = 45, hjust = 1
))
Works like a charm (adapted from Allan Cameron's answer)
CodePudding user response:
The values
argument has to be numbers between 0 and 1 (representing the upper and lower limits of the scale), so you need something like:
ggplot(mtcars2, aes(x = rownames(mtcars), y = 1, fill = ratio3))
geom_tile()
theme_minimal()
scale_fill_gradientn(
colours = c("blue", "white", "red"),
na.value = "grey98",
name = "ratio",
limits = c(0, ifelse(max(mtcars2$ratio3) > 1, max(mtcars2$ratio3), 1)),
values = c(0, ifelse(max(mtcars2$ratio3) > 1, 1/max(mtcars2$ratio3), 1), 1)
)
theme_classic()
theme(axis.text.x = element_text(
size = 10, face = "bold", color = "black",
angle = 45, hjust = 1
))
CodePudding user response:
I think there are two options.
Option 1: If you want the scale to be symmetric around 1, you can set the rescaler
argument of the scale to set 1 as the middle. This might work somewhat better after log-transform and setting 0 as the center.
library(ggplot2)
set.seed(0)
df <- data.frame(
x = 1:20,
y = 2,
value = rlnorm(20)
)
ggplot(df, aes(x, y, fill = value))
geom_tile()
scale_fill_gradientn(
colours=c("blue", "white", "red"),
na.value = "grey98", name = "ratio",
rescaler = ~ scales::rescale_mid(.x, mid = 1)
)
Option 2: If you don't particularly care if the scale is symmetric, you can use the values
argument. I think the thing you might've overlooked in your code is that the values()
should be between 0 and 1. To get the colours into that range, you need to divide by the maximum value.
ggplot(df, aes(x, y, fill = value))
geom_tile()
scale_fill_gradientn(
colours=c("blue", "white", "red"),
na.value = "grey98", name = "ratio",
values = c(0, 1, max(df$value))/max(df$value)
)
Created on 2022-08-17 by the reprex package (v2.0.1)