Reputation: 501
I am trying to generate a heatmap table using ggplot in R. My data looks this:
dt <- cbind(rbinom(1:10,100,0.9), rbinom(1:10,100,0.5), rbinom(1:10,100,0.2), rbinom(1:10,100,0.05)
colnames(dt) <- c("A","B","C","D")
I want to use different gradient colors for each category to emphasize the importance of each value. Since the range of values is large, the smaller number will be colored almost same. That's why, I want to use different colors. My code is here:
library(dplyr)
library(ggplot2)
library(reshape2)
library(scales)
dt <- cbind(rbinom(1:10,100,0.9), rbinom(1:10,100,0.5), rbinom(1:10,100,0.2), rbinom(1:10,100,0.01))
colnames(dt) <- c("A","B","C","D")
dt <- melt(dt)
dt %>%
ggplot(aes(Var2,Var1)) +
geom_tile(aes(fill = value), colour = "white") +
geom_text(aes(fill = dt$value, label = dt$value, 3), size = 4) +
scale_fill_gradient2(low = "green", mid = "yellow", high = "red", midpoint = 0.05) +
theme(panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank(),
panel.grid.major.y = element_blank(),
panel.grid.minor.y = element_blank(),
panel.background = element_rect(fill = "white"),
axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1, size = 10, face = "bold"),
plot.title = element_text(size = 20, face = "bold"),
axis.text.y = element_text(size = 10, face = "bold")) +
ggtitle("Heatmap Table") +
theme(legend.title = element_text(face = "bold", size = 14)) +
scale_x_discrete(name = "") +
scale_y_discrete(name = "") +
labs(fill = "Heatmap")
The plot looks like this:
The colors should be gradient in each category. I really appreciate any help.
Upvotes: 4
Views: 2303
Reputation: 16832
Assuming I'm interpreting your question correctly, I changed the variable that is mapped to fill. Instead of the raw value you have, I grouped by Var2 and calculated a relative value, so each value is scaled compared to the other values in its group---e.g. how does this value compare to all others in group A.
I also took out the 3 from your geom_text
aes
because it seemed like a typo. That lets the text geoms each take the same positions as the corresponding tiles.
One drawback to this approach is that the labels on the legend don't have a lot of meaning now, or at least would need some explanation to say that values are scaled against their group.
Edit: I'm changing the midpoint in the color gradient to 0.5 instead of the previous 0.05, so the minimum colors still show after scaling values.
library(dplyr)
library(ggplot2)
library(reshape2)
library(scales)
dt <- cbind(rbinom(1:10,100,0.9), rbinom(1:10,100,0.5), rbinom(1:10,100,0.2), rbinom(1:10,100,0.01))
colnames(dt) <- c("A","B","C","D")
dt <- melt(dt)
dt %>%
group_by(Var2) %>%
# make a variable for the value scaled in relation to other values in that group
mutate(rel_value = value / max(value)) %>%
ggplot(aes(Var2,Var1)) +
geom_tile(aes(fill = rel_value), colour = "white") +
# take out dt$...
# take out 3 from aes
geom_text(aes(label = value), size = 4) +
scale_fill_gradient2(low = "green", mid = "yellow", high = "red", midpoint = 0.5) +
theme(panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank(),
panel.grid.major.y = element_blank(),
panel.grid.minor.y = element_blank(),
panel.background = element_rect(fill = "white"),
axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1, size = 10, face = "bold"),
plot.title = element_text(size = 20, face = "bold"),
axis.text.y = element_text(size = 10, face = "bold")) +
ggtitle("Heatmap Table") +
theme(legend.title = element_text(face = "bold", size = 14)) +
scale_x_discrete(name = "") +
scale_y_discrete(name = "") +
labs(fill = "Heatmap")
Created on 2018-04-16 by the reprex package (v0.2.0).
Upvotes: 3