-1

I'm looking for an easy way to create a custom heat map (in Python, or R, or Tableau). I can't figure out how to personalise colours as I need them.

Basically, I have a .tsv file with feature and their ranking. The ranking goes, for example, from 1 to 10 and from -1 to -10 in the same file.

I need to have white for zeros. Then, darker colours for 1 and -1 that then becomes lighter. So, for example, I need to have dark red for 1 and light red for 10, and then dark blue for -1 and light blue for -10.

Any idea on how I could obtain this result?


edit: This is how my data look:

structure(list(Features = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 
7L, 8L, 11L, 12L, 9L, 10L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 
20L, 21L), .Label = c("char_per_tok", "cpos_dist_AUX", "cpos_dist_NUM", 
"dep_dist_aux", "dep_dist_nummod", "dep_freq_aux", "dep_freq_nmod", 
"dep_freq_nummod", "in_dict", "in_dict_types", "in_FO", "in_FO_types", 
"itwac_forme", "itwac_lemmi", "n_prepositional_chains", "prep_dist_3", 
"prep_freq_1", "prep_freq_3", "subj_post", "verb_edges_dist_7", 
"verb_edges_freq_7"), class = "factor"), A10 = c(1L, -14L, -6L, 
-8L, -5L, -7L, 3L, -3L, -1L, -11L, -2L, -4L, 0L, 59L, 4L, -9L, 
2L, -10L, 0L, -13L, -12L), A11 = c(3L, -14L, -6L, -8L, -5L, -7L, 
4L, -4L, -1L, -11L, -2L, -3L, 1L, 2L, 0L, -9L, 5L, -10L, 0L, 
-13L, -12L), A12 = c(3L, 0L, -3L, -5L, -2L, -4L, 0L, -1L, 0L, 
0L, 0L, 0L, 1L, 2L, 0L, -6L, 0L, -7L, 0L, -9L, -8L), A13 = c(3L, 
0L, -3L, 0L, -2L, 0L, 0L, -1L, 0L, 0L, 0L, 0L, 1L, 2L, 0L, -4L, 
0L, -5L, 0L, 0L, 0L), A14 = c(1L, 0L, -3L, 0L, -2L, 0L, 0L, -1L, 
0L, 0L, 0L, 0L, 0L, 2L, 0L, -4L, 0L, -5L, 0L, 0L, 0L), A15 = c(2L, 
0L, -3L, 0L, -2L, 0L, 0L, -1L, 0L, 0L, 0L, 0L, 1L, 3L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L), A16 = c(0L, 0L, -4L, -5L, -1L, 0L, 0L, -2L, 
0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, -3L, 0L, 0L)), .Names = c("Features", 
"A10", "A11", "A12", "A13", "A14", "A15", "A16"), class = "data.frame", row.names = c(NA, 
-21L))
Bet
  • 3
  • 2
  • 1
    What have you done so far? An example of how you have created a heatmap without your specified colours would be helpful to understand where you need help. – asongtoruin Sep 22 '17 at 10:47

3 Answers3

1

In R you can use ggplot2 library, geom_tile to specify what is plotted and scale_fill_gradientn to specify the colors. Here is an example:

#diamonds + column rank with a range of -10:10
library(ggplot2)
data(diamonds)
diamonds_1= data.frame(diamonds, rank = sample(c(-10:10), nrow(diamonds), replace = T))


ggplot(data = diamonds_1)+
  geom_tile(aes(color, cut, fill = rank))+
  scale_fill_gradientn(colors = c("lightblue", "blue", "white", "red", "pink"),
                       values = scales::rescale(c(-10, -1, 0, 1, 10)))+
  coord_equal()

enter image description here

EDIT: with provided data (I imported it to object z)

z_melt = reshape2::melt(z, id.vars = 1 ) #convert to long format
library(ggplot2)
ggplot(data = z_melt)+
  geom_tile(aes(y = Features,  x = variable, fill = value))+
  scale_fill_gradientn(colors = c("#ccccff", "lightblue", "blue", "white", "red", "#ff7f7f", "#ffcccc"),
                       values = scales::rescale(c(min(z_melt$value), -10, -1, 0, 1, 10, max(z_melt$value))),
                       breaks = c(-10, 0, 10, 40),
                       labels=c(-10, 0, 10, 40))+                           
  coord_equal()+
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

enter image description here

missuse
  • 19,056
  • 3
  • 25
  • 47
  • Thank you, this is actually the type of coloring I was looking for! – Bet Sep 24 '17 at 18:14
  • I added a picture of my data. Can you please explain me how to plot them so that I obtain the same result of your picture? – Bet Sep 27 '17 at 22:10
  • @Bet please provide data with `dput` or at least in the form of text table. – missuse Sep 28 '17 at 05:11
  • Thank you! is there a way to still have 'white' for zero values? Just like what you did in the first table – Bet Sep 28 '17 at 10:32
  • @Bet I am sorry I assumed the fill variable is in: -10 - 10 range. Fixed the graph. – missuse Sep 28 '17 at 10:51
0

in R, you can use the scales package to generate the color values.

To generate the colors, use gradient_n_pal. Choose the color you want for the negative values, the color for the positives, and then place "white" between them. seq(0, 1, length.out = 21) creates a vector of length 21 that sets the fading.

gradient <- scales::gradient_n_pal(c("purple", "white", "green"))(seq(0, 1, length.out = 21))

This trivial barplot shows the result

library(ggplot2)

Dframe <- data.frame(x = factor(-10:10)) 

ggplot(data = Dframe,
       mapping = aes(x = x)) + 
  geom_bar(fill = gradient)

enter image description here

Benjamin
  • 16,897
  • 6
  • 45
  • 65
0

To create the colour chart in Tableau: If you want individual colours for each rank simply drag your [Ranking] dimension to colour. If you want a banded output you can create a colour key calculated field, firstly assign a value to each ranking by creating a new calculated field like:

If [Ranking] = -10 then "Cold"
ElseIf [Ranking] = -9 then "Cold"
ElseIf [Ranking] = -8 then "Cold"
ElseIf [Ranking] = -7 then "Cold"
ElseIf [Ranking] = -6 then "Cold"
ElseIf [Ranking] = -5 then "Warm"
ElseIf [Ranking] = -4 then "Warm"
ElseIf [Ranking] = -3 then "Warm"
ElseIf [Ranking] = -2 then "Warm"
ElseIf [Ranking] = -1 then "Warm"
ElseIf [Ranking] = -0 then "Warm"
ElseIf [Ranking] = 1 then "Warm"
ElseIf [Ranking] = 2 then "Warm"
ElseIf [Ranking] = 3 then "Warm"
ElseIf [Ranking] = 4 then "Warm"
ElseIf [Ranking] = 5 then "Hot"
ElseIf [Ranking] = 6 then "Hot"
ElseIf [Ranking] = 7 then "Hot"
ElseIf [Ranking] = 8 then "Hot"
ElseIf [Ranking] = 9 then "Hot"
ElseIf [Ranking] = 10 then "Hot"
else "Unknown ranking"  end

Drag this field to colour and you can apply a palate of your choice to it.

This is a slightly long winded way of writing the calculated field, depending on the formatting of your ranking field you could use between number bands instead, but writing it this way makes it clear what's going on for each score.

Ben P
  • 3,267
  • 4
  • 26
  • 53