Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

ggplot2 - R: Change colorPalette colors in risk heatmap using ggplot

Thank you for looking at my question. I have created a heat map with a color gradient. The color gradient looks good, however, I would prefer that the colors be more defined. The first picture that I have attached here

Heatmap

is what I get when I run my code. The second picture

Desired Heatmap is what I would like to get. I am not sure how to solve this problem. A small sample of my code is below. To be clear, I would like for my code to return the second picture where the colors distinctly go from green, gold, orange, light red, red, and dark red.

library(RColorBrewer)
library(dplyr)
library(ggplot2)

nRow <- 5 
nCol <- 5 
m3 <- matrix(c(2,2,3,3,3,1,2,2,3,3,1,1,2,2,3,1,1,2,2,2,1,1,1,1,2), nrow = 5, ncol = 5, byrow = TRUE)
myData <- m3 #matrix(rnorm(nRow * nCol), ncol = nCol)
rownames(myData) <- c("5", "4", "3", "2","1")  
colnames(myData) <- c("1", "2", "3", "4","5")  
longData <- reshape2::melt(myData)
colnames(longData) <- c("Likelihood", "Consequence", "value")
longData <- mutate(longData, value = Consequence * Likelihood)

cols <-function(n) {
  colorRampPalette(rev(c("red4","red2","tomato2","orange","gold1","forestgreen")))(6)                                
}

display_risk <-  mutate(longData, value = Consequence * Likelihood)

ggplot(longData,aes(x = Consequence, y = Likelihood, fill = value))  +
  geom_tile() +
  scale_fill_gradientn(colours = cols(6)) +
  theme(axis.text.y = element_text(angle=90, hjust=1), legend.position = "none") +
  scale_x_continuous(name = "Probability", breaks = seq(1,5,1), expand = c(0, 0)) +
  scale_y_reverse(name= "Severity", breaks = seq(1,5,1), expand = c(0, 0)) +
  geom_hline(yintercept = seq(1.5,5.5)) +
  geom_vline(xintercept = seq(1.5,5.5)) +
  coord_fixed()

Here are some links to a few answers that I tried with no luck.

question from:https://stackoverflow.com/questions/65849678/r-change-colorpalette-colors-in-risk-heatmap-using-ggplot

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I can hardly think of a different way than to map your desired colors to specific value ranges. See below. Please check how I reduced your code, there were lots of unnecessary calls, (I guess you've copied it from a script where you have tried different stuff). Also, I have changed the colorRampPalette call - this is a function generator, no need to use function() here.

Notice you would need to manually define the values, and I guess this would be your researcher decision how to present the data. You need to scale it to a range 0:1

library(RColorBrewer)
library(dplyr)
library(ggplot2)

myData <- matrix(c(2,2,3,3,3,1,2,2,3,3,1,1,2,2,3,1,1,2,2,2,1,1,1,1,2), nrow = 5, ncol = 5, byrow = TRUE)
longData <- reshape2::melt(myData)
colnames(longData) <- c("Likelihood", "Consequence", "value")
longData <- mutate(longData, value = Consequence * Likelihood)
mycols <- rev(c("red4","red2","tomato2","orange","gold1","forestgreen"))
cols <- colorRampPalette(mycols)

myvals <- c(0, 8, 9, 10, 11, 25)
scaled_val <- scales::rescale(myvals, 0:1)

ggplot(longData, aes(x = Consequence, y = Likelihood, fill = value)) +
  geom_tile() +
  scale_fill_gradientn(colours = cols(length(mycols)), 
                       values = scaled_val) +
  theme(axis.text.y = element_text(angle = 90, hjust = 1), legend.position = "none") +
  scale_x_continuous(name = "Probability", breaks = seq(1, 5, 1), expand = c(0, 0)) +
  scale_y_reverse(name = "Severity", breaks = seq(1, 5, 1), expand = c(0, 0)) +
  geom_hline(yintercept = seq(1.5, 5.5)) +
  geom_vline(xintercept = seq(1.5, 5.5)) +
  coord_fixed()

Additionally you can define from where your gradient shall start. I've shown how to do this I a very recent thread. Note your desired output does not match the values (I've superimposed them to demonstrate that). Also notice this all is obviously all defined by yourself - those values that I chose are random, and it's up to you to tweak it to your liking.


myvals <- c(0, 6, 7, 9, 10, 11, 25)
scaled_val <- scales::rescale(myvals, 0:1)

ggplot(longData, aes(x = Consequence, y = Likelihood, fill = value)) +
  geom_tile() +
  geom_text(aes(label = value)) +
  scale_fill_gradientn(colours = c(mycols[1], mycols), 
                       values = scaled_val) +
  theme(axis.text.y = element_text(angle = 90, hjust = 1), legend.position = "none") +
  scale_x_continuous(name = "Probability", breaks = seq(1, 5, 1), expand = c(0, 0)) +
  scale_y_reverse(name = "Severity", breaks = seq(1, 5, 1), expand = c(0, 0)) +
  geom_hline(yintercept = seq(1.5, 5.5)) +
  geom_vline(xintercept = seq(1.5, 5.5)) +
  coord_fixed()


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...