|
a |
|
b/aggmap/utils/vismap.py |
|
|
1 |
from scipy.cluster.hierarchy import dendrogram, linkage, to_tree |
|
|
2 |
from scipy.spatial.distance import squareform |
|
|
3 |
import seaborn as sns |
|
|
4 |
from highcharts import Highchart |
|
|
5 |
import pandas as pd |
|
|
6 |
import numpy as np |
|
|
7 |
import os |
|
|
8 |
|
|
|
9 |
from aggmap.utils.logtools import print_info |
|
|
10 |
|
|
|
11 |
|
|
|
12 |
def plot_scatter(mp, htmlpath = './', htmlname = None, radius = 2, enabled_data_labels = False): |
|
|
13 |
''' |
|
|
14 |
mp: the object of mp |
|
|
15 |
htmlpath: the figure path, not include the prefix of 'html' |
|
|
16 |
htmlname: the name |
|
|
17 |
radius: int, defaut:3, the radius of scatter dot |
|
|
18 |
''' |
|
|
19 |
|
|
|
20 |
title = '2D emmbedding of %s based on %s method' % (mp.ftype, mp.emb_method) |
|
|
21 |
subtitle = 'number of %s: %s, metric method: %s' % (mp.ftype, len(mp.flist), mp.metric) |
|
|
22 |
name = '%s_%s_%s_%s_%s' % (mp.ftype,len(mp.flist), mp.metric, mp.emb_method, 'scatter') |
|
|
23 |
|
|
|
24 |
if not os.path.exists(htmlpath): |
|
|
25 |
os.makedirs(htmlpath) |
|
|
26 |
|
|
|
27 |
if htmlname: |
|
|
28 |
name = htmlname + '_' + name |
|
|
29 |
|
|
|
30 |
filename = os.path.join(htmlpath, name) |
|
|
31 |
print_info('generate file: %s' % filename) |
|
|
32 |
|
|
|
33 |
colormaps = mp.colormaps |
|
|
34 |
df = mp.df_scatter |
|
|
35 |
|
|
|
36 |
H = Highchart(width=1000, height=850) |
|
|
37 |
H.set_options('chart', {'type': 'scatter', 'zoomType': 'xy'}) |
|
|
38 |
H.set_options('title', {'text': title}) |
|
|
39 |
H.set_options('subtitle', {'text': subtitle}) |
|
|
40 |
H.set_options('xAxis', {'title': {'enabled': True,'text': 'X', 'style':{'fontSize':20}}, |
|
|
41 |
'labels':{'style':{'fontSize':20}}, |
|
|
42 |
'gridLineWidth': 1, |
|
|
43 |
'startOnTick': True, |
|
|
44 |
'endOnTick': True, |
|
|
45 |
'showLastLabel': True}) |
|
|
46 |
|
|
|
47 |
H.set_options('yAxis', {'title': {'text': 'Y', 'style':{'fontSize':20}}, |
|
|
48 |
'labels':{'style':{'fontSize':20}}, |
|
|
49 |
'gridLineWidth': 1,}) |
|
|
50 |
|
|
|
51 |
# H.set_options('legend', {'layout': 'horizontal','verticalAlign': 'top','align':'right','floating': False, |
|
|
52 |
# 'backgroundColor': "(Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'", |
|
|
53 |
# 'borderWidth': 1}) |
|
|
54 |
|
|
|
55 |
|
|
|
56 |
H.set_options('legend', {'align': 'right', 'layout': 'vertical', |
|
|
57 |
'margin': 1, 'verticalAlign': 'top', 'y':40, |
|
|
58 |
'symbolHeight': 12, 'floating': False,}) |
|
|
59 |
|
|
|
60 |
|
|
|
61 |
H.set_options('plotOptions', {'scatter': {'marker': {'radius': radius, |
|
|
62 |
'states': {'hover': {'enabled': True, |
|
|
63 |
'lineColor': 'rgb(100,100,100)'}}}, |
|
|
64 |
'states': {'hover': {'marker': {'enabled': False} }}, |
|
|
65 |
'tooltip': {'headerFormat': '<b>{series.name}</b><br>', |
|
|
66 |
'pointFormat': '{point.IDs}'}}, |
|
|
67 |
'series': {'turboThreshold': 5000, |
|
|
68 |
'dataLabels': {'enabled': enabled_data_labels, 'format': '{point.IDs}'}} |
|
|
69 |
}) |
|
|
70 |
|
|
|
71 |
for subtype, color in colormaps.items(): |
|
|
72 |
dfi = df[df['Subtypes'] == subtype] |
|
|
73 |
if len(dfi) == 0: |
|
|
74 |
continue |
|
|
75 |
|
|
|
76 |
data = dfi.to_dict('records') |
|
|
77 |
H.add_data_set(data, 'scatter', subtype, color=color) |
|
|
78 |
H.save_file(filename) |
|
|
79 |
print_info('save html file to %s' % filename) |
|
|
80 |
return H |
|
|
81 |
|
|
|
82 |
|
|
|
83 |
|
|
|
84 |
def plot_grid(mp, htmlpath = './', htmlname = None, enabled_data_labels = False): |
|
|
85 |
''' |
|
|
86 |
mp: the object of mp |
|
|
87 |
htmlpath: the figure path |
|
|
88 |
''' |
|
|
89 |
|
|
|
90 |
if not os.path.exists(htmlpath): |
|
|
91 |
os.makedirs(htmlpath) |
|
|
92 |
|
|
|
93 |
title = 'Assignment of %s by %s emmbedding result' % (mp.ftype, mp.emb_method) |
|
|
94 |
subtitle = 'number of %s: %s, metric method: %s' % (mp.ftype, len(mp.flist), mp.metric) |
|
|
95 |
|
|
|
96 |
name = '%s_%s_%s_%s_%s' % (mp.ftype,len(mp.flist), mp.metric, mp.emb_method, 'mp') |
|
|
97 |
|
|
|
98 |
if htmlname: |
|
|
99 |
name = name = htmlname + '_' + name |
|
|
100 |
|
|
|
101 |
filename = os.path.join(htmlpath, name) |
|
|
102 |
print_info('generate file: %s' % filename) |
|
|
103 |
|
|
|
104 |
colormaps = mp.colormaps |
|
|
105 |
df = mp.df_grid |
|
|
106 |
|
|
|
107 |
H = Highchart(width=1000, height=850) |
|
|
108 |
H.set_options('chart', {'type': 'heatmap', 'zoomType': 'xy'}) |
|
|
109 |
H.set_options('title', {'text': title}) |
|
|
110 |
H.set_options('subtitle', {'text': subtitle}) |
|
|
111 |
# H.set_options('xAxis', {'title': '', |
|
|
112 |
# 'min': 0, 'max': mp._S.fmap_shape[1]-1, |
|
|
113 |
# 'allowDecimals':False, |
|
|
114 |
# 'labels':{'style':{'fontSize':20}}}) |
|
|
115 |
|
|
|
116 |
# H.set_options('yAxis', {'title': '', 'tickPosition': 'inside', |
|
|
117 |
# 'min': 0, 'max': mp._S.fmap_shape[0]-1, |
|
|
118 |
# 'reversed': True, |
|
|
119 |
# 'allowDecimals':False, |
|
|
120 |
# 'labels':{'style':{'fontSize':20}}}) |
|
|
121 |
|
|
|
122 |
H.set_options('xAxis', {'title': None, |
|
|
123 |
'min': 0, 'max': mp.fmap_shape[1]-1, |
|
|
124 |
'startOnTick': False, |
|
|
125 |
'endOnTick': False, |
|
|
126 |
'allowDecimals':False, |
|
|
127 |
'labels':{'style':{'fontSize':20}}}) |
|
|
128 |
|
|
|
129 |
|
|
|
130 |
H.set_options('yAxis', {'title': {'text': ' ', 'style':{'fontSize':20}}, |
|
|
131 |
'startOnTick': False, |
|
|
132 |
'endOnTick': False, |
|
|
133 |
'gridLineWidth': 0, |
|
|
134 |
'reversed': True, |
|
|
135 |
'min': 0, 'max': mp.fmap_shape[0]-1, |
|
|
136 |
'allowDecimals':False, |
|
|
137 |
'labels':{'style':{'fontSize':20}}}) |
|
|
138 |
|
|
|
139 |
|
|
|
140 |
|
|
|
141 |
H.set_options('legend', {'align': 'right', 'layout': 'vertical', |
|
|
142 |
'margin': 1, 'verticalAlign': 'top', |
|
|
143 |
'y': 60, 'symbolHeight': 12, 'floating': False,}) |
|
|
144 |
|
|
|
145 |
|
|
|
146 |
H.set_options('tooltip', {'headerFormat': '<b>{series.name}</b><br>', |
|
|
147 |
'pointFormat': '{point.v}'}) |
|
|
148 |
|
|
|
149 |
|
|
|
150 |
H.set_options('plotOptions', {'series': {'turboThreshold': 5000, |
|
|
151 |
'dataLabels': {'enabled': enabled_data_labels, |
|
|
152 |
'format': '{point.v}', |
|
|
153 |
'style': {'textOutline':False, 'color': 'black'}, |
|
|
154 |
|
|
|
155 |
} |
|
|
156 |
} |
|
|
157 |
} |
|
|
158 |
) |
|
|
159 |
|
|
|
160 |
for subtype, color in colormaps.items(): |
|
|
161 |
dfi = df[df['Subtypes'] == subtype] |
|
|
162 |
if len(dfi) == 0: |
|
|
163 |
continue |
|
|
164 |
H.add_data_set(dfi.to_dict('records'), 'heatmap', |
|
|
165 |
name = subtype, |
|
|
166 |
#dataLabels = {'enabled': True, 'color': color} |
|
|
167 |
color = color, |
|
|
168 |
) |
|
|
169 |
H.save_file(filename) |
|
|
170 |
print_info('save html file to %s' % filename) |
|
|
171 |
|
|
|
172 |
return H |
|
|
173 |
|
|
|
174 |
|
|
|
175 |
|
|
|
176 |
|
|
|
177 |
|
|
|
178 |
|
|
|
179 |
def _getNewick(node, newick, parentdist, leaf_names): |
|
|
180 |
if node.is_leaf(): |
|
|
181 |
return "%s:%.2f%s" % (leaf_names[node.id], parentdist - node.dist, newick) |
|
|
182 |
else: |
|
|
183 |
if len(newick) > 0: |
|
|
184 |
newick = "):%.2f%s" % (parentdist - node.dist, newick) |
|
|
185 |
else: |
|
|
186 |
newick = ");" |
|
|
187 |
newick = _getNewick(node.get_left(), newick, node.dist, leaf_names) |
|
|
188 |
newick = _getNewick(node.get_right(), ",%s" % (newick), node.dist, leaf_names) |
|
|
189 |
newick = "(%s" % (newick) |
|
|
190 |
return newick |
|
|
191 |
|
|
|
192 |
def _mp2newick(mp, treefile = 'mytree'): |
|
|
193 |
|
|
|
194 |
dist_matrix = mp.dist_matrix |
|
|
195 |
leaf_names = mp.flist |
|
|
196 |
df = mp.df_embedding[['colors','Subtypes']] |
|
|
197 |
|
|
|
198 |
dists = squareform(dist_matrix) |
|
|
199 |
linkage_matrix = linkage(dists, 'complete') |
|
|
200 |
tree = to_tree(linkage_matrix, rd=False) |
|
|
201 |
newick = getNewick(tree, "", tree.dist, leaf_names = leaf_names) |
|
|
202 |
|
|
|
203 |
with open(treefile + '.nwk', 'w') as f: |
|
|
204 |
f.write(newick) |
|
|
205 |
df.to_excel(treefile + '.xlsx') |
|
|
206 |
|
|
|
207 |
|
|
|
208 |
def plot_tree(mp, htmlpath = './', htmlname = None): |
|
|
209 |
pass |