George Sotiropoulos
George Sotiropoulos

Reputation: 2123

Heat map when the color is scaled rowwise

Hello stackoverflowers!

As the title is indicating I want to make a heat map but the color scaling should be across each row and individual of each other.

The following example will indicate what I want exactly:

library(tidyverse)
library(data.table)
data_heat <- expand.grid(y = letters[seq( from = 1, to = 6 )],x = LETTERS[ seq( from = 1, to = 10 )]) %>% as.data.table()
data_heat %>% setkey(y)
data_heat[, fill_value := seq(from = 1,to =  nrow(data_heat))]


data_heat%>% ggplot(aes(x = x, y = y)) + 
  geom_tile(aes(fill = fill_value), colour = "black") + scale_fill_gradient(low = "green",
                                                                              high = "red") + 
  theme(axis.text.x = element_text(angle = 30, hjust = 1)) +    geom_text(aes(label = fill_value)) 

this is going to generate:

basic heat map

while what I want is that the right side of the graph is red because there are the largest values per row.

Upvotes: 5

Views: 2563

Answers (2)

Andrew Lavers
Andrew Lavers

Reputation: 4378

A more basic data manipulation approach:

library(dplyr)
data_heat_summary <- data_heat %>%
  group_by(y) %>%
  summarize(mx = max(fill_value), mn = min(fill_value)) 

data_heat %>% 
  inner_join(data_heat_summary) %>%
  mutate(p = (fill_value - mn ) / (mx - mn)) %>%
  ggplot(aes(x = x, y = y)) + 
  geom_tile(aes(fill = p), colour = "black") + 
  scale_fill_gradient(low = "green", high = "red") + 
  theme(axis.text.x = element_text(angle = 30, hjust = 1)) +    geom_text(aes(label = fill_value)) 

Upvotes: 3

pogibas
pogibas

Reputation: 28309

Solution:

Scale values using function scale() per each group (data_heat$y).

Code:

library(ggplot2)
library(data.table)
data_heat[, fillScaled := scale(fill_value), y]
ggplot(data_heat, aes(x, y)) + 
    geom_tile(aes(fill = fillScaled), colour = "black") + 
    scale_fill_gradient(low = "green", high = "red") + 
    geom_text(aes(label = fill_value)) +
    theme(axis.text.x = element_text(angle = 30, hjust = 1))

Result:

enter image description here

Data (data_heat):

structure(list(y = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L, 6L), .Label = c("a", "b", "c", "d", "e", "f"), class = "factor"), 
    x = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 
    1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 
    5L, 6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 
    9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 1L, 2L, 
    3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L), .Label = c("A", "B", "C", 
    "D", "E", "F", "G", "H", "I", "J"), class = "factor"), fill_value = 1:60), .Names = c("y", 
"x", "fill_value"), out.attrs = structure(list(dim = structure(c(6L, 
10L), .Names = c("y", "x")), dimnames = structure(list(y = c("y=a", 
"y=b", "y=c", "y=d", "y=e", "y=f"), x = c("x=A", "x=B", "x=C", 
"x=D", "x=E", "x=F", "x=G", "x=H", "x=I", "x=J")), .Names = c("y", 
"x"))), .Names = c("dim", "dimnames")), class = c("data.table", 
"data.frame"), row.names = c(NA, -60L))

Upvotes: 5

Related Questions