nik
nik

Reputation: 2584

how to make a merged heatmap between each two columns of values

How can I put two columns in one heatmap? Lets say I have the following data

data<- structure(list(names = structure(c(5L, 1L, 10L, 2L, 6L, 4L, 9L, 
7L, 11L, 3L, 8L), .Label = c("Bin", "Dari", "Down", "How", "India", 
"Karachi", "Left", "middle", "Right", "Trash", "Up"), class = "factor"), 
    X1Huor = c(1.555555556, 5.2555556, 2.256544, 2.3654225, 1.2665545, 
    0, 1.889822365, 2.37232101, -1, -1.885618083, 1.128576187
    ), X2Hour = c(1.36558854, 2.254887, 2.3333333, 0.22255444, 
    2.256588, 5.66666, -0.377964473, 0.107211253, -1, 0, 0), 
    X3Hour = c(0, 1.222222222, 5.336666, 1.179323788, 0.832050294, 
    -0.397359707, 0.185695338, 1.393746295, -1, -2.121320344, 
    1.523019248), X4Hour = c(3.988620176, 3.544745039, -2.365555, 
    2.366666, 1.000000225, -0.662266179, -0.557086015, 0.862662186, 
    0, -1.305459824, 1.929157714), X5Hour = c(2.366666, 2.333365, 
    4.22222, 0.823333333, 0.980196059, -2.516611478, 2.267786838, 
    0.32163376, 0, -2.592724864, 0.816496581)), .Names = c("names", 
"X1Huor", "X2Hour", "X3Hour", "X4Hour", "X5Hour"), class = "data.frame", row.names = c(NA, 
-11L))

This data has 5 columns of values. I want to make a heatmap which half of it is the value from first colum and the other half of each cell is from the second column.

The same for the third column and fourth

The same for the fifth and sixth ( there is no sixth but I can leave it empty)

This is just an example to show what I am looking for. I have searched a lot but I could not find anything like this

enter image description here

The color range from Red to green, if the value is higher than 2 the color red and if the value is lower than -2 the color is green.

Any thought how to do this ?

Upvotes: 2

Views: 649

Answers (1)

yeedle
yeedle

Reputation: 5008

This is a somewhat hacky solution, but it might work for you, so check this out.

The idea is to utilize geom_polygon to create the triangles and stack them. To do that we first need to generate the triangle coordinates

library(dplyr)
library(tidyr)
library(stringr)

# the following two line create the triangle coordinates
x = rep(c(1,2,2, 1, 1, 2),nrow(data))
y = rep(c(1,1,2, 1, 2, 2),nrow(data)) + rep(0:10, each=6)

Now that we have our coordinates we need to generate their ids, which are the names. But because we want each triangle to be unique, we need to create two unique versions of each name:

names <- data %>% 
  select(names, X1Huor, X2Hour) %>% 
  gather("key", "value", X1Huor, X2Hour) %>%
  arrange(names, key) %>% 
  mutate(name = str_c(names, key)) %>%
  .$name %>% 
  rep(each = 3)

And now we do the same with the hours:

hour <- data %>% 
  select(names, X1Huor, X2Hour) %>% 
  gather("key", "value", X1Huor, X2Hour) %>%
  arrange(names, key) %>% 
  .$value %>% 
  rep(each = 3)

datapoly <- data.frame(x = x, y = y , hour = hour, names = names)

Since there are no proper labels for the plot in our datapoly df, we need to create one:

name_labels <- data %>% 
  select(names) %>% 
  arrange(names) %>%
  .$names

The scene is now set for our graph:

ggplot(datapoly, aes(x = x, y = y)) +
  geom_polygon(aes(group = names, fill = hour), color = "black") +
  scale_fill_continuous(low = "green", high = "red") +
  scale_y_continuous(breaks = 1:nrow(data), labels = name_labels) +
  theme(axis.text.y = element_text(vjust = -2),
        axis.ticks = element_blank(),
        axis.text.x = element_blank(),
        axis.title = element_blank())

The output looks like this:

plot

Several points to keep in mind: Is this really a plot you want to be creating and using? Is this really useful for your purposes? Perhaps other, more traditional visualization methods are more suitable. Also, I didn't bother doing the same for the other hour columns as these are quite tedious, but the method on how to achieve them should be clear enough (I hope).

Upvotes: 2

Related Questions