I want to make a heatmap with different colours in the upper and lower triangles. This works as I expect:
library(ggnewscale)
library(ggplot2)
library(dplyr)
data <- data.frame(
Var1 = c("b", "c", "a", "c", "a", "b"),
Var2 = c("a", "a", "b", "b", "c", "c"),
val = c(-2.1113581, 0.6189813, -0.4770620, 0.8119133, -0.4029937, 0.7977290)
)
plot_data = data %>%
mutate(triangle = ifelse(Var1 < Var2, "Lower", "Upper")) %>%
group_split(triangle)
ggplot() +
geom_tile(data=plot_data[[1]], aes(x=Var1, y=Var2, fill=val)) +
scale_fill_gradient(low = "lightblue", high = "blue", name = "Upper Values") +
new_scale_fill() + # Part of ggnewscale, allows multiple fill scales
# Lower triangle heatmap with a green color scale
geom_tile(data = plot_data[[2]], aes(x=Var1, y=Var2, fill=val)) +
scale_fill_gradient(low = "lightgreen", high = "darkgreen", name = "Lower Values")
However, when I try and order the axes, then it ends up switching over some of the colours from the triangles, i.e. Var1 = b and Var2 = a is now blue rather than green:
ggplot() +
geom_tile(data=plot_data[[1]], aes(x=Var1, y=Var2, fill=val)) +
scale_fill_gradient(low = "lightblue", high = "blue", name = "Upper Values") +
new_scale_fill() + # Part of ggnewscale, allows multiple fill scales
# Lower triangle heatmap with a green color scale
geom_tile(data = plot_data[[2]], aes(x=Var1, y=Var2, fill=val)) +
scale_fill_gradient(low = "lightgreen", high = "darkgreen", name = "Lower Values") +
scale_x_discrete(limits = c("b", "a", "c")) +
scale_y_discrete(limits = c("b", "a", "c"))
How can I keep the right colours in the upper and lower triangles and keep a particular order of the factors?
Instead of setting the order via the limits=
convert your variables to factor
s with the desired order (and set drop=FALSE
in scale_x/y_discrete
).
library(ggnewscale)
library(ggplot2)
library(dplyr, warn = FALSE)
plot_data <- data %>%
mutate(
Var1 = factor(Var1, c("b", "a", "c")),
Var2 = factor(Var2, c("b", "a", "c"))
) |>
mutate(triangle = ifelse(as.integer(Var1) < as.integer(Var2), "Lower", "Upper")) %>%
group_split(triangle)
ggplot() +
geom_tile(data = plot_data[[1]], aes(x = Var1, y = Var2, fill = val)) +
scale_x_discrete(drop = FALSE) +
scale_y_discrete(drop = FALSE) +
scale_fill_gradient(low = "lightblue", high = "blue", name = "Upper Values") +
new_scale_fill() +
geom_tile(data = plot_data[[2]], aes(x = Var1, y = Var2, fill = val)) +
scale_fill_gradient(low = "lightgreen", high = "darkgreen", name = "Lower Values")