-
Notifications
You must be signed in to change notification settings - Fork 0
/
heatmap.py
78 lines (60 loc) · 2.6 KB
/
heatmap.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
'''
@author: Leila Arras
@maintainer: Leila Arras
@date: 21.06.2017
@version: 1.0+
@copyright: Copyright (c) 2017, Leila Arras, Gregoire Montavon, Klaus-Robert Mueller, Wojciech Samek
@license: see LICENSE file in repository root
'''
import matplotlib.pyplot as plt
def rescale_score_by_abs (score, max_score, min_score):
"""
Normalize the relevance value (=score), accordingly to the extremal relevance values (max_score and min_score),
for visualization with a diverging colormap.
i.e. rescale positive relevance to the range [0.5, 1.0], and negative relevance to the range [0.0, 0.5],
using the highest absolute relevance for linear interpolation.
"""
# CASE 1: positive AND negative scores occur --------------------
if max_score>0 and min_score<0:
if max_score >= abs(min_score): # deepest color is positive
if score>=0:
return 0.5 + 0.5*(score/max_score)
else:
return 0.5 - 0.5*(abs(score)/max_score)
else: # deepest color is negative
if score>=0:
return 0.5 + 0.5*(score/abs(min_score))
else:
return 0.5 - 0.5*(score/min_score)
# CASE 2: ONLY positive scores occur -----------------------------
elif max_score>0 and min_score>=0:
if max_score == min_score:
return 1.0
else:
return 0.5 + 0.5*(score/max_score)
# CASE 3: ONLY negative scores occur -----------------------------
elif max_score<=0 and min_score<0:
if max_score == min_score:
return 0.0
else:
return 0.5 - 0.5*(score/min_score)
def getRGB (c_tuple):
return "#%02x%02x%02x"%(int(c_tuple[0]*255), int(c_tuple[1]*255), int(c_tuple[2]*255))
def span_word (word, score, colormap):
return "<span style=\"background-color:"+getRGB(colormap(score))+"\">"+word+"</span>"
def html_heatmap (words, scores, cmap_name="bwr"):
"""
Return word-level heatmap in HTML format,
with words being the list of words (as string),
scores the corresponding list of word-level relevance values,
and cmap_name the name of the matplotlib diverging colormap.
"""
colormap = plt.get_cmap(cmap_name)
assert len(words)==len(scores)
max_s = max(scores)
min_s = min(scores)
output_text = ""
for idx, w in enumerate(words):
score = rescale_score_by_abs(scores[idx], max_s, min_s)
output_text = output_text + span_word(w, score, colormap) + " "
return output_text + "\n"