|
a |
|
b/R/3-3.plot.R |
|
|
1 |
# ========4.plot======== |
|
|
2 |
|
|
|
3 |
|
|
|
4 |
#' Plot a metanet |
|
|
5 |
#' |
|
|
6 |
#' @param x metanet object |
|
|
7 |
#' @param ... add |
|
|
8 |
#' |
|
|
9 |
#' @return plot |
|
|
10 |
#' @exportS3Method |
|
|
11 |
#' @method plot metanet |
|
|
12 |
plot.metanet <- function(x, ...) { |
|
|
13 |
# 具有n_type的metanet的默认参数记录在这里,用于快速绘图。 |
|
|
14 |
go <- x |
|
|
15 |
if (is.null(get_n(go)$n_type)) { |
|
|
16 |
c_net_plot(go, ...) |
|
|
17 |
} else if (get_n(go)$n_type == "skeleton") { |
|
|
18 |
skeleton_plot(go, ...) |
|
|
19 |
} else if (get_n(go)$n_type == "module") { |
|
|
20 |
default_arg <- list( |
|
|
21 |
labels_num = 0, |
|
|
22 |
group_legend_title = "Module" |
|
|
23 |
) |
|
|
24 |
do.call(c_net_plot, append(list(go = go), pcutils::update_param(default_arg, list(...)))) |
|
|
25 |
} else if (get_n(go)$n_type == "venn") { |
|
|
26 |
nice_size <- ceiling(60 / sqrt(length(V(go)))) + 1 |
|
|
27 |
default_arg <- list( |
|
|
28 |
labels_num = "all", |
|
|
29 |
vertex_size_range = list("Group" = c(1.5 * nice_size, 1.5 * nice_size), "elements" = c(0.5 * nice_size, 0.5 * nice_size)), |
|
|
30 |
vertex.shape = "circle", |
|
|
31 |
legend = FALSE, edge.curved = 0.3, |
|
|
32 |
edge.color = unique(V(go)$color) |
|
|
33 |
) |
|
|
34 |
do.call(c_net_plot, append(list(go = go), pcutils::update_param(default_arg, list(...)))) |
|
|
35 |
} else if (get_n(go)$n_type == "twocol") { |
|
|
36 |
nice_size <- ceiling(60 / sqrt(length(V(go)))) + 1 |
|
|
37 |
default_arg <- list( |
|
|
38 |
labels_num = 0, |
|
|
39 |
vertex.shape = "circle", |
|
|
40 |
edge_legend = FALSE, |
|
|
41 |
edge.color = "black" |
|
|
42 |
) |
|
|
43 |
do.call(c_net_plot, append(list(go = go), pcutils::update_param(default_arg, list(...)))) |
|
|
44 |
} else if (get_n(go)$n_type == "ko_net") { |
|
|
45 |
nice_size <- ceiling(60 / sqrt(length(V(go)))) + 1 |
|
|
46 |
default_arg <- list( |
|
|
47 |
labels_num = "all", |
|
|
48 |
vertex.shape = "circle", |
|
|
49 |
vertex_size_range = list("Pathway" = c(1.2 * nice_size, 1.2 * nice_size), "KOs" = c(0.6 * nice_size, 0.6 * nice_size)), |
|
|
50 |
edge_legend = FALSE, |
|
|
51 |
edge.color = "black", |
|
|
52 |
mark_alpha = 0.1 |
|
|
53 |
) |
|
|
54 |
do.call(c_net_plot, append(list(go = go), pcutils::update_param(default_arg, list(...)))) |
|
|
55 |
} else { |
|
|
56 |
c_net_plot(go, ...) |
|
|
57 |
} |
|
|
58 |
} |
|
|
59 |
|
|
|
60 |
get_net_main <- function(n_index) { |
|
|
61 |
main <- "Network" |
|
|
62 |
if (!is.null(n_index$n_type)) { |
|
|
63 |
switch(n_index$n_type, |
|
|
64 |
"single" = { |
|
|
65 |
main <- "Correlation network" |
|
|
66 |
}, |
|
|
67 |
"bipartite" = { |
|
|
68 |
main <- "Bipartite network" |
|
|
69 |
}, |
|
|
70 |
"multi_full" = { |
|
|
71 |
main <- "Multi-omics network" |
|
|
72 |
}, |
|
|
73 |
"module" = { |
|
|
74 |
main <- paste0(n_index$n_modules, "-modules network") |
|
|
75 |
}, |
|
|
76 |
"skeleton" = { |
|
|
77 |
main <- paste0(n_index$skeleton, " skeleton network") |
|
|
78 |
}, |
|
|
79 |
"venn" = { |
|
|
80 |
main <- "Venn network" |
|
|
81 |
}, |
|
|
82 |
default = { |
|
|
83 |
main <- "Network" |
|
|
84 |
} |
|
|
85 |
) |
|
|
86 |
} |
|
|
87 |
return(main) |
|
|
88 |
} |
|
|
89 |
|
|
|
90 |
scale_size_width <- function(tmp_v, tmp_e, vertex_size_range, edge_width_range) { |
|
|
91 |
{ v_groups <- unique(tmp_v$v_group) |
|
|
92 |
nice_size <- ceiling(100 / sqrt(nrow(tmp_v))) + 1 |
|
|
93 |
|
|
|
94 |
vertex_size_range_default <- rep(list(c(max(nice_size * 0.4, 3), min(nice_size * 1.6, 12))), length(v_groups)) |
|
|
95 |
names(vertex_size_range_default) <- v_groups |
|
|
96 |
|
|
|
97 |
if (!is.null(vertex_size_range)) { |
|
|
98 |
if (!is.list(vertex_size_range)) vertex_size_range <- list(vertex_size_range) |
|
|
99 |
if (is.null(names(vertex_size_range))) { |
|
|
100 |
vertex_size_range <- rep(vertex_size_range, length(v_groups)) |
|
|
101 |
names(vertex_size_range) <- v_groups |
|
|
102 |
} |
|
|
103 |
vertex_size_range <- pcutils::update_param(vertex_size_range_default, vertex_size_range) |
|
|
104 |
} else { |
|
|
105 |
vertex_size_range <- vertex_size_range_default |
|
|
106 |
} |
|
|
107 |
|
|
|
108 |
node_size_text <- setNames(as.list(numeric(length(v_groups))), v_groups) |
|
|
109 |
for (i in v_groups) { |
|
|
110 |
node_size_text[[i]] <- c( |
|
|
111 |
min(tmp_v[tmp_v$v_group == i, "size"], na.rm = TRUE), |
|
|
112 |
max(tmp_v[tmp_v$v_group == i, "size"], na.rm = TRUE) |
|
|
113 |
) |
|
|
114 |
tmp_v[tmp_v$v_group == i, "size"] <- do.call(pcutils::mmscale, append( |
|
|
115 |
list(tmp_v[tmp_v$v_group == i, "size"]), |
|
|
116 |
as.list(sort(vertex_size_range[[i]][1:2])) |
|
|
117 |
)) |
|
|
118 |
} } |
|
|
119 |
|
|
|
120 |
{ |
|
|
121 |
edge_width_range_default <- vertex_size_range_default[[1]] / 6 |
|
|
122 |
if (is.null(edge_width_range)) edge_width_range <- edge_width_range_default |
|
|
123 |
edge_width_range <- sort(edge_width_range) |
|
|
124 |
edge_width_text <- c(min(tmp_e$width, na.rm = TRUE), max(tmp_e$width, na.rm = TRUE)) |
|
|
125 |
tmp_e$width <- pcutils::mmscale(tmp_e$width, edge_width_range[1], edge_width_range[2]) |
|
|
126 |
} |
|
|
127 |
|
|
|
128 |
envir <- parent.frame() |
|
|
129 |
assign("node_size_text", node_size_text, envir) |
|
|
130 |
assign("edge_width_text", edge_width_text, envir) |
|
|
131 |
assign("tmp_e", tmp_e, envir) |
|
|
132 |
assign("tmp_v", tmp_v, envir) |
|
|
133 |
} |
|
|
134 |
|
|
|
135 |
some_custom_paras <- function(tmp_v, tmp_e, ...) { |
|
|
136 |
params <- list(...) |
|
|
137 |
params_name <- names(params) |
|
|
138 |
|
|
|
139 |
# 下列都是mapping好的颜色,形状等,无法单独修改某一个vertex或edge的颜色,形状等 |
|
|
140 |
# !!!考虑增加额外参数,用于单独修改某一个vertex或edge的颜色,形状等 |
|
|
141 |
if (!"label.color" %in% colnames(tmp_v)) tmp_v$label.color <- "black" |
|
|
142 |
if ("vertex.size" %in% params_name) tmp_v$size <- params[["vertex.size"]] |
|
|
143 |
if ("vertex.color" %in% params_name) { |
|
|
144 |
tmp_v$color <- condance(data.frame( |
|
|
145 |
tmp_v$color, |
|
|
146 |
pcutils::tidai(tmp_v$v_class, params[["vertex.color"]], fac = TRUE) |
|
|
147 |
)) |
|
|
148 |
} |
|
|
149 |
if ("vertex.shape" %in% params_name) { |
|
|
150 |
tmp_v$shape <- condance(data.frame( |
|
|
151 |
tmp_v$shape, |
|
|
152 |
pcutils::tidai(tmp_v$v_group, params[["vertex.shape"]]) |
|
|
153 |
)) |
|
|
154 |
} |
|
|
155 |
if ("vertex.label" %in% params_name) tmp_v$label <- params[["vertex.label"]] |
|
|
156 |
if ("vertex.label.color" %in% params_name) { |
|
|
157 |
tmp_v$label.color <- condance(data.frame( |
|
|
158 |
"black", |
|
|
159 |
pcutils::tidai(tmp_v$v_group, params[["vertex.label.color"]], fac = TRUE) |
|
|
160 |
)) |
|
|
161 |
} |
|
|
162 |
|
|
|
163 |
if ("edge.color" %in% params_name) { |
|
|
164 |
tmp_e$color <- condance(data.frame( |
|
|
165 |
tmp_e$color, |
|
|
166 |
pcutils::tidai(tmp_e$e_type, params[["edge.color"]], fac = TRUE) |
|
|
167 |
)) |
|
|
168 |
} |
|
|
169 |
if ("edge.lty" %in% params_name) { |
|
|
170 |
tmp_e$lty <- condance(data.frame( |
|
|
171 |
tmp_e$lty, |
|
|
172 |
pcutils::tidai(tmp_e$e_class, params[["edge.lty"]], fac = TRUE) |
|
|
173 |
)) |
|
|
174 |
} |
|
|
175 |
if ("edge.width" %in% params_name) tmp_e$width <- params[["edge.width"]] |
|
|
176 |
|
|
|
177 |
envir <- parent.frame() |
|
|
178 |
assign("tmp_e", tmp_e, envir) |
|
|
179 |
assign("tmp_v", tmp_v, envir) |
|
|
180 |
} |
|
|
181 |
|
|
|
182 |
pie_set_for_plot <- function(tmp_v, pie_value, pie_color) { |
|
|
183 |
if ("pie" %in% tmp_v$shape) { |
|
|
184 |
if (!is.null(pie_value)) { |
|
|
185 |
if (!is.data.frame(pie_value)) stop("pie_value must be a data.frame.") |
|
|
186 |
if (!"name" %in% colnames(pie_value)) { |
|
|
187 |
pie_value$name <- rownames(pie_value) |
|
|
188 |
} |
|
|
189 |
if (any(duplicated(pie_value$name))) { |
|
|
190 |
stop( |
|
|
191 |
"Duplicated name in annotation tables: ", |
|
|
192 |
paste0(pie_value$name[duplicated(pie_value$name)], collapse = ", ") |
|
|
193 |
) |
|
|
194 |
} |
|
|
195 |
tmp_merge_df <- left_join(tmp_v["name"], pie_value, by = "name") |
|
|
196 |
pie_value <- tmp_merge_df[, -1] |
|
|
197 |
pie_parts <- colnames(pie_value) |
|
|
198 |
|
|
|
199 |
pie_value[is.na(pie_value)] <- 0 |
|
|
200 |
pie_value$`__others` <- ifelse(rowSums(pie_value) > 0, 0, 1) |
|
|
201 |
pie_value_list <- as.list(pcutils::t2(pie_value)) |
|
|
202 |
|
|
|
203 |
default_pie_color <- setNames(pcutils::get_cols(length(pie_parts), "col1"), pie_parts) |
|
|
204 |
if (is.null(pie_color)) pie_color <- default_pie_color |
|
|
205 |
if (is.null(names(pie_color))) { |
|
|
206 |
pie_color <- setNames(pie_color, pie_parts) |
|
|
207 |
} else { |
|
|
208 |
pie_color <- pcutils::update_param(default_pie_color, pie_color) |
|
|
209 |
} |
|
|
210 |
|
|
|
211 |
pie_color <- pie_color[pie_parts] |
|
|
212 |
pie_color <- c(pie_color, `__others` = NA) |
|
|
213 |
} else { |
|
|
214 |
pie_value_list <- pie_color <- NULL |
|
|
215 |
} |
|
|
216 |
} else { |
|
|
217 |
pie_value_list <- pie_color <- NULL |
|
|
218 |
} |
|
|
219 |
envir <- parent.frame() |
|
|
220 |
assign("pie_value_list", pie_value_list, envir) |
|
|
221 |
assign("pie_color", pie_color, envir) |
|
|
222 |
} |
|
|
223 |
|
|
|
224 |
get_show_labels <- function(tmp_v, labels_num) { |
|
|
225 |
name <- size <- NULL |
|
|
226 |
if (is.null(labels_num)) { |
|
|
227 |
if (nrow(tmp_v) < 20) { |
|
|
228 |
labels_num <- "all" |
|
|
229 |
} else { |
|
|
230 |
labels_num <- 0 |
|
|
231 |
} |
|
|
232 |
} |
|
|
233 |
{ |
|
|
234 |
if (labels_num == "all") { |
|
|
235 |
tmp_v %>% dplyr::pull(name) -> toplabel |
|
|
236 |
} else { |
|
|
237 |
if (labels_num >= 1) { |
|
|
238 |
tmp_v %>% |
|
|
239 |
dplyr::top_n(labels_num, size) %>% |
|
|
240 |
dplyr::arrange(-size) %>% |
|
|
241 |
dplyr::pull(name) %>% |
|
|
242 |
head(labels_num) -> toplabel |
|
|
243 |
} else { |
|
|
244 |
tmp_v %>% |
|
|
245 |
dplyr::top_frac(labels_num, size) %>% |
|
|
246 |
dplyr::arrange(-size) %>% |
|
|
247 |
dplyr::pull(name) %>% |
|
|
248 |
head(ceiling(labels_num * nrow(tmp_v))) -> toplabel |
|
|
249 |
} |
|
|
250 |
} |
|
|
251 |
tmp_v$label <- ifelse(tmp_v$name %in% toplabel, tmp_v$label, NA) |
|
|
252 |
} |
|
|
253 |
return(tmp_v) |
|
|
254 |
} |
|
|
255 |
|
|
|
256 |
module_set_for_plot <- function(tmp_v, mark_module, mark_color) { |
|
|
257 |
if (mark_module) { |
|
|
258 |
new_modu <- as_module(setNames(tmp_v$module, tmp_v$name)) |
|
|
259 |
new_modu[["others"]] <- NULL |
|
|
260 |
|
|
|
261 |
module_color <- pcutils::get_cols(length(new_modu)) |
|
|
262 |
if (!is.null(mark_color)) module_color <- condance(data.frame(module_color, pcutils::tidai(names(new_modu), mark_color))) |
|
|
263 |
|
|
|
264 |
module_color <- setNames(module_color, names(new_modu)) |
|
|
265 |
module_color <- module_color[names(module_color) != "others"] |
|
|
266 |
} else { |
|
|
267 |
new_modu <- module_color <- NULL |
|
|
268 |
} |
|
|
269 |
envir <- parent.frame() |
|
|
270 |
assign("new_modu", new_modu, envir) |
|
|
271 |
assign("module_color", module_color, envir) |
|
|
272 |
} |
|
|
273 |
|
|
|
274 |
get_module_coors <- function(go = NULL, coors = NULL, tmp_v = NULL, ori_coors = NULL, module_label_just = c(0.5, 0.5), rescale_flag = TRUE) { |
|
|
275 |
X <- Y <- module <- minx <- maxx <- miny <- maxy <- NULL |
|
|
276 |
if (is.null(go)) { |
|
|
277 |
if (is.null(tmp_v) && is.null(ori_coors)) message("input `tmp_v` and `ori_coors` when `go` is null.") |
|
|
278 |
} else { |
|
|
279 |
tmp_v <- get_v(go) |
|
|
280 |
ori_coors <- get_coors(coors, go) |
|
|
281 |
} |
|
|
282 |
module_coors <- dplyr::left_join(tmp_v[, c("name", "module")], ori_coors, by = "name") |
|
|
283 |
if (rescale_flag) module_coors <- dplyr::mutate(module_coors, X = mmscale(X, -1, 1), Y = mmscale(Y, -1, 1)) |
|
|
284 |
module_coors <- dplyr::group_by(module_coors, module) %>% |
|
|
285 |
dplyr::summarise(minx = min(X), maxx = max(X), miny = min(Y), maxy = max(Y)) |
|
|
286 |
module_label_just <- rep(module_label_just, 2) |
|
|
287 |
module_coors <- mutate(module_coors, |
|
|
288 |
X = minx + module_label_just[1] * (maxx - minx), |
|
|
289 |
Y = miny + module_label_just[2] * (maxy - miny) |
|
|
290 |
) |
|
|
291 |
return(module_coors) |
|
|
292 |
} |
|
|
293 |
|
|
|
294 |
produce_c_net_legends <- function(tmp_v, tmp_e, vertex_frame_width, |
|
|
295 |
legend_position, legend_number, legend_cex, |
|
|
296 |
node_size_text, edge_width_text, |
|
|
297 |
group_legend_title, group_legend_order, |
|
|
298 |
color_legend, color_legend_order, |
|
|
299 |
size_legend, size_legend_title, |
|
|
300 |
edge_legend, edge_legend_title, edge_legend_order, |
|
|
301 |
width_legend, width_legend_title, |
|
|
302 |
lty_legend, lty_legend_title, lty_legend_order, |
|
|
303 |
module_legend, module_legend_title, module_legend_order, module_color, mark_alpha, |
|
|
304 |
pie_legend, pie_legend_title, pie_legend_order, pie_color, |
|
|
305 |
...) { |
|
|
306 |
color <- e_type <- lty <- e_class <- v_class <- shape <- left_leg_x <- right_leg_x <- NULL |
|
|
307 |
|
|
|
308 |
legend_position_default <- c(left_leg_x = -2, left_leg_y = 1, right_leg_x = 1.2, right_leg_y = 1) |
|
|
309 |
|
|
|
310 |
if (is.null(legend_position)) legend_position <- legend_position_default |
|
|
311 |
if (is.null(names(legend_position))) { |
|
|
312 |
legend_position <- setNames(legend_position, names(legend_position_default)[seq_along(legend_position)]) |
|
|
313 |
} |
|
|
314 |
legend_position <- pcutils::update_param(legend_position_default, legend_position) |
|
|
315 |
here_env <- environment() |
|
|
316 |
lapply(names(legend_position), \(i){ |
|
|
317 |
assign(i, legend_position[i], here_env) |
|
|
318 |
}) |
|
|
319 |
|
|
|
320 |
vgroups <- pcutils::change_fac_lev(tmp_v$v_group, group_legend_order) |
|
|
321 |
vgroups <- levels(vgroups) |
|
|
322 |
|
|
|
323 |
if (color_legend) { |
|
|
324 |
# !!!考虑添加更多的形状,至少是21:25,形状为pie时添加额外legend |
|
|
325 |
|
|
|
326 |
if (is.null(group_legend_title)) { |
|
|
327 |
group_legend_title <- setNames(vgroups, vgroups) |
|
|
328 |
} else if (is.null(names(group_legend_title))) { |
|
|
329 |
group_legend_title <- setNames(rep(group_legend_title, len = length(vgroups)), vgroups) |
|
|
330 |
} |
|
|
331 |
|
|
|
332 |
this_shape <- unique(tmp_v$shape) |
|
|
333 |
if (!all(this_shape %in% names(default_v_shape))) { |
|
|
334 |
default_v_shape <- pcutils::update_param( |
|
|
335 |
default_v_shape, |
|
|
336 |
setNames(rep(21, length(this_shape)), this_shape) |
|
|
337 |
) |
|
|
338 |
} |
|
|
339 |
|
|
|
340 |
for (g_i in vgroups) { |
|
|
341 |
if ("count" %in% names(tmp_v)) { |
|
|
342 |
tmp_v1 <- tmp_v[tmp_v$v_group == g_i, c("v_class", "color", "shape", "count")] |
|
|
343 |
} else { |
|
|
344 |
tmp_v1 <- tmp_v[tmp_v$v_group == g_i, c("v_class", "color", "shape")] |
|
|
345 |
} |
|
|
346 |
|
|
|
347 |
tmp_v1$v_class <- factor(tmp_v1$v_class, levels = custom_sort(unique(tmp_v1$v_class))) |
|
|
348 |
|
|
|
349 |
vclass <- pcutils::change_fac_lev(tmp_v1$v_class, color_legend_order) |
|
|
350 |
vclass <- levels(vclass) |
|
|
351 |
|
|
|
352 |
node_cols <- dplyr::distinct(tmp_v1, color, v_class) |
|
|
353 |
node_cols <- setNames(node_cols$color, node_cols$v_class) |
|
|
354 |
node_shapes <- dplyr::distinct(tmp_v1, shape, v_class) |
|
|
355 |
node_shapes <- setNames(node_shapes$shape, node_shapes$v_class) |
|
|
356 |
|
|
|
357 |
if (legend_number) { |
|
|
358 |
eee <- table(tmp_v1$v_class) |
|
|
359 |
if (!is.null(attributes(tmp_v)$skeleton)) { |
|
|
360 |
eee <- setNames(tmp_v1$count, tmp_v1$v_class) |
|
|
361 |
legend_number <- FALSE |
|
|
362 |
} |
|
|
363 |
le_text <- paste(vclass, eee[vclass], sep = ": ") |
|
|
364 |
} else { |
|
|
365 |
le_text <- vclass |
|
|
366 |
} |
|
|
367 |
if (length(le_text) == 0) le_text <- "" |
|
|
368 |
legend(left_leg_x, left_leg_y, |
|
|
369 |
cex = 0.7 * legend_cex, adj = 0, pt.lwd = vertex_frame_width, |
|
|
370 |
legend = le_text, title.cex = 0.8 * legend_cex, |
|
|
371 |
title = group_legend_title[g_i], title.font = 2, title.adj = 0, |
|
|
372 |
col = "black", pt.bg = node_cols[vclass], bty = "n", pch = default_v_shape[node_shapes[vclass]] |
|
|
373 |
) |
|
|
374 |
|
|
|
375 |
left_leg_y <- left_leg_y - (length(vclass) * 0.12 + 0.2) * legend_cex |
|
|
376 |
} |
|
|
377 |
} |
|
|
378 |
|
|
|
379 |
if (module_legend) { |
|
|
380 |
tmp_v$module <- factor(tmp_v$module, levels = custom_sort(unique(tmp_v$module))) |
|
|
381 |
modules <- pcutils::change_fac_lev(tmp_v$module, module_legend_order) |
|
|
382 |
modules <- levels(modules) |
|
|
383 |
|
|
|
384 |
if (legend_number) { |
|
|
385 |
eee <- table(tmp_v$module) |
|
|
386 |
le_text <- paste(modules, eee[modules], sep = ": ") |
|
|
387 |
} else { |
|
|
388 |
le_text <- modules |
|
|
389 |
} |
|
|
390 |
legend(left_leg_x, left_leg_y, |
|
|
391 |
cex = 0.7 * legend_cex, adj = 0, |
|
|
392 |
legend = le_text, title.cex = 0.8 * legend_cex, |
|
|
393 |
title = module_legend_title, title.font = 2, title.adj = 0, |
|
|
394 |
fill = pcutils::add_alpha(module_color[modules], mark_alpha), |
|
|
395 |
border = module_color[modules], bty = "n" |
|
|
396 |
) |
|
|
397 |
|
|
|
398 |
left_leg_y <- left_leg_y - (length(modules) * 0.12 + 0.2) * legend_cex |
|
|
399 |
} |
|
|
400 |
|
|
|
401 |
if (pie_legend) { |
|
|
402 |
pie_color <- pie_color[names(pie_color) != "__others"] |
|
|
403 |
pies <- pcutils::change_fac_lev(names(pie_color), pie_legend_order) |
|
|
404 |
pies <- levels(pies) |
|
|
405 |
|
|
|
406 |
le_text <- pies |
|
|
407 |
legend(left_leg_x, left_leg_y, |
|
|
408 |
cex = 0.7 * legend_cex, adj = 0, |
|
|
409 |
legend = le_text, title.cex = 0.8 * legend_cex, |
|
|
410 |
title = pie_legend_title, title.font = 2, title.adj = 0, |
|
|
411 |
fill = pie_color[pies], |
|
|
412 |
border = "black", bty = "n" |
|
|
413 |
) |
|
|
414 |
left_leg_y <- left_leg_y - (length(pies) * 0.12 + 0.2) * legend_cex |
|
|
415 |
} |
|
|
416 |
|
|
|
417 |
if (size_legend) { |
|
|
418 |
legend( |
|
|
419 |
x = right_leg_x, y = right_leg_y, |
|
|
420 |
cex = 0.7 * legend_cex, title.font = 2, title = size_legend_title, title.adj = 0, |
|
|
421 |
legend = c( |
|
|
422 |
paste(lapply(node_size_text[vgroups], \(i)round(i[1], 3)), collapse = "/ "), |
|
|
423 |
paste(lapply(node_size_text[vgroups], \(i)round(i[2], 3)), collapse = "/ ") |
|
|
424 |
), |
|
|
425 |
adj = 0, title.cex = 0.8 * legend_cex, |
|
|
426 |
col = "black", bty = "n", pch = 21, pt.cex = c(min(tmp_v$size), max(tmp_v$size)) * legend_cex / 5 |
|
|
427 |
) |
|
|
428 |
right_leg_y <- right_leg_y - 0.5 * legend_cex |
|
|
429 |
} |
|
|
430 |
|
|
|
431 |
if (edge_legend) { |
|
|
432 |
tmp_e$e_type <- factor(tmp_e$e_type, levels = custom_sort(unique(tmp_e$e_type))) |
|
|
433 |
edges <- pcutils::change_fac_lev(tmp_e$e_type, edge_legend_order) |
|
|
434 |
edges <- levels(edges) |
|
|
435 |
edge_cols <- dplyr::distinct(tmp_e, color, e_type) |
|
|
436 |
edge_cols <- setNames(edge_cols$color, edge_cols$e_type) |
|
|
437 |
if (legend_number) { |
|
|
438 |
eee <- table(tmp_e$e_type) |
|
|
439 |
le_text <- paste(edges, eee[edges], sep = ": ") |
|
|
440 |
} else { |
|
|
441 |
le_text <- edges |
|
|
442 |
} |
|
|
443 |
legend(right_leg_x, right_leg_y, |
|
|
444 |
cex = 0.7 * legend_cex, title.font = 2, title = edge_legend_title, title.adj = 0, |
|
|
445 |
legend = le_text, adj = 0, title.cex = 0.8 * legend_cex, |
|
|
446 |
col = edge_cols[edges], bty = "n", lty = 1 |
|
|
447 |
) |
|
|
448 |
right_leg_y <- right_leg_y - (length(unique(tmp_e$color)) * 0.12 + 0.2) * legend_cex |
|
|
449 |
} |
|
|
450 |
|
|
|
451 |
if (width_legend) { |
|
|
452 |
legend(right_leg_x, right_leg_y, |
|
|
453 |
cex = 0.7 * legend_cex, title.font = 2, title = width_legend_title, title.adj = 0, |
|
|
454 |
legend = edge_width_text %>% round(., 3), adj = 0, title.cex = 0.8 * legend_cex, |
|
|
455 |
col = "black", bty = "n", lty = 1, lwd = c(min(tmp_e$width), max(tmp_e$width)) |
|
|
456 |
) |
|
|
457 |
right_leg_y <- right_leg_y - 0.5 * legend_cex |
|
|
458 |
} |
|
|
459 |
|
|
|
460 |
if (lty_legend) { |
|
|
461 |
edges <- pcutils::change_fac_lev(tmp_e$e_class, lty_legend_order) |
|
|
462 |
edges <- levels(edges) |
|
|
463 |
edge_ltys <- dplyr::distinct(tmp_e, lty, e_class) |
|
|
464 |
edge_ltys <- setNames(edge_ltys$lty, edge_ltys$e_class) |
|
|
465 |
|
|
|
466 |
if (legend_number) { |
|
|
467 |
eee <- table(tmp_e$e_class) |
|
|
468 |
le_text <- paste(edges, eee[edges], sep = ": ") |
|
|
469 |
} else { |
|
|
470 |
le_text <- edges |
|
|
471 |
} |
|
|
472 |
legend(right_leg_x, right_leg_y, |
|
|
473 |
cex = 0.7 * legend_cex, title.font = 2, title = lty_legend_title, title.adj = 0, |
|
|
474 |
legend = le_text, adj = 0, title.cex = 0.8 * legend_cex, |
|
|
475 |
col = "black", bty = "n", lty = edge_ltys[edges] |
|
|
476 |
) |
|
|
477 |
} |
|
|
478 |
} |
|
|
479 |
|
|
|
480 |
#' Plot a metanet |
|
|
481 |
#' |
|
|
482 |
#' @param go an igraph or metanet object |
|
|
483 |
#' @param coors the coordinates you saved |
|
|
484 |
#' @param ... additional parameters for \code{\link[igraph]{igraph.plotting}} |
|
|
485 |
#' @param labels_num show how many labels, >1 indicates number, <1 indicates fraction, "all" indicates all. |
|
|
486 |
#' @param vertex_size_range the vertex size range, e.g. c(1,10) |
|
|
487 |
#' @param edge_width_range the edge width range, e.g. c(1,10) |
|
|
488 |
#' |
|
|
489 |
#' @param plot_module logical, plot module? |
|
|
490 |
#' @param mark_module logical, mark the modules? |
|
|
491 |
#' @param mark_color mark color |
|
|
492 |
#' @param mark_alpha mark fill alpha, default 0.3 |
|
|
493 |
#' @param module_label show module label? |
|
|
494 |
#' @param module_label_cex module label cex |
|
|
495 |
#' @param module_label_color module label color |
|
|
496 |
#' @param module_label_just module label just, default c(0.5,0.5) |
|
|
497 |
#' |
|
|
498 |
#' @param pie_value a dataframe using to plot pie (with rowname or a "name" column) |
|
|
499 |
#' @param pie_color color vector |
|
|
500 |
#' |
|
|
501 |
#' @param legend all legends |
|
|
502 |
#' @param legend_number legend with numbers |
|
|
503 |
#' @param legend_cex character expansion factor relative to current par("cex"), default: 1 |
|
|
504 |
#' @param legend_position legend_position, default: c(left_leg_x=-1.9,left_leg_y=1,right_leg_x=1.2,right_leg_y=1) |
|
|
505 |
#' |
|
|
506 |
#' @param group_legend_title group_legend_title, length must same to the numbers of v_group |
|
|
507 |
#' @param group_legend_order group_legend_order vector |
|
|
508 |
#' @param color_legend logical |
|
|
509 |
#' @param color_legend_order color_legend_order vector |
|
|
510 |
#' @param size_legend logical |
|
|
511 |
#' @param size_legend_title size_legend_title |
|
|
512 |
#' |
|
|
513 |
#' @param edge_legend logical |
|
|
514 |
#' @param edge_legend_title edge_legend_title |
|
|
515 |
#' @param edge_legend_order edge_legend_order vector, e.g. c("positive","negative") |
|
|
516 |
#' @param width_legend logical |
|
|
517 |
#' @param width_legend_title width_legend_title |
|
|
518 |
#' |
|
|
519 |
#' @param lty_legend logical |
|
|
520 |
#' @param lty_legend_title lty_legend_title |
|
|
521 |
#' @param lty_legend_order lty_legend_order |
|
|
522 |
#' |
|
|
523 |
#' @param module_legend logical |
|
|
524 |
#' @param module_legend_title module_legend_title |
|
|
525 |
#' @param module_legend_order module_legend_order |
|
|
526 |
#' |
|
|
527 |
#' @param pie_legend logical |
|
|
528 |
#' @param pie_legend_title pie_legend_title |
|
|
529 |
#' @param pie_legend_order pie_legend_order |
|
|
530 |
#' |
|
|
531 |
#' @param seed random seed, default:1234, make sure each plot is the same. |
|
|
532 |
#' @param params_list a list of parameters, e.g. list(edge_legend = TRUE, lty_legend = FALSE), when the parameter is duplicated, the format argument will be used rather than the argument in params_list. |
|
|
533 |
#' @param rescale Logical constant, whether to rescale the coordinates to the (-1,1). |
|
|
534 |
#' |
|
|
535 |
#' @family plot |
|
|
536 |
#' @return a network plot |
|
|
537 |
#' @export |
|
|
538 |
#' |
|
|
539 |
#' @examples |
|
|
540 |
#' data("c_net") |
|
|
541 |
#' c_net_plot(co_net) |
|
|
542 |
#' c_net_plot(co_net2) |
|
|
543 |
#' c_net_plot(multi1) |
|
|
544 |
c_net_plot <- function(go, coors = NULL, ..., labels_num = NULL, |
|
|
545 |
vertex_size_range = NULL, edge_width_range = NULL, |
|
|
546 |
plot_module = FALSE, |
|
|
547 |
mark_module = FALSE, mark_color = NULL, mark_alpha = 0.3, |
|
|
548 |
module_label = FALSE, module_label_cex = 2, module_label_color = "black", |
|
|
549 |
module_label_just = c(0.5, 0.5), |
|
|
550 |
pie_value = NULL, pie_color = NULL, |
|
|
551 |
legend = TRUE, legend_number = FALSE, legend_cex = 1, |
|
|
552 |
legend_position = c(left_leg_x = -2, left_leg_y = 1, right_leg_x = 1.2, right_leg_y = 1), |
|
|
553 |
group_legend_title = NULL, group_legend_order = NULL, |
|
|
554 |
color_legend = TRUE, color_legend_order = NULL, |
|
|
555 |
size_legend = FALSE, size_legend_title = "Node Size", |
|
|
556 |
edge_legend = TRUE, edge_legend_title = "Edge type", edge_legend_order = NULL, |
|
|
557 |
width_legend = FALSE, width_legend_title = "Edge width", |
|
|
558 |
lty_legend = FALSE, lty_legend_title = "Edge class", lty_legend_order = NULL, |
|
|
559 |
module_legend = FALSE, module_legend_title = "Module", module_legend_order = NULL, |
|
|
560 |
pie_legend = FALSE, pie_legend_title = "Pie part", pie_legend_order = NULL, |
|
|
561 |
params_list = NULL, rescale = FALSE, |
|
|
562 |
seed = 1234) { |
|
|
563 |
if (!is.null(params_list)) { |
|
|
564 |
as.list(match.call()[-1]) -> set_params_list |
|
|
565 |
set_params_list[["params_list"]] <- NULL |
|
|
566 |
for (i in seq_along(params_list)) { |
|
|
567 |
if (names(params_list)[i] %in% names(set_params_list)) { |
|
|
568 |
message("The parameter `", names(params_list)[i], "` is duplicated, the format argument will be used.") |
|
|
569 |
} |
|
|
570 |
} |
|
|
571 |
pcutils::update_param(params_list, set_params_list) -> set_params_list |
|
|
572 |
do.call(c_net_plot, set_params_list) |
|
|
573 |
return(invisible()) |
|
|
574 |
} |
|
|
575 |
|
|
|
576 |
if (length(V(go)) == 0) { |
|
|
577 |
message("The network is empty.") |
|
|
578 |
return(invisible()) |
|
|
579 |
} |
|
|
580 |
new_modu <- module_color <- node_size_text <- edge_width_text <- NULL |
|
|
581 |
set.seed(seed) |
|
|
582 |
|
|
|
583 |
if (!is_metanet(go)) go <- c_net_update(go) |
|
|
584 |
# go <- c_net_update(go) |
|
|
585 |
|
|
|
586 |
# modules |
|
|
587 |
if (plot_module) { |
|
|
588 |
go <- to_module_net(go) |
|
|
589 |
if (is.null(group_legend_title)) group_legend_title <- "Module" |
|
|
590 |
} |
|
|
591 |
|
|
|
592 |
# get network type |
|
|
593 |
get_net_main(get_n(go)) -> main |
|
|
594 |
get_v(go) -> tmp_v |
|
|
595 |
get_e(go) -> tmp_e |
|
|
596 |
|
|
|
597 |
# get coordinates |
|
|
598 |
ori_coors <- get_coors(coors, go, seed = seed) |
|
|
599 |
coors <- ori_coors[, c("X", "Y")] %>% as.matrix() |
|
|
600 |
if (is.null(attributes(ori_coors)$curved)) { |
|
|
601 |
edge_curved <- NULL |
|
|
602 |
} else { |
|
|
603 |
edge_curved <- attributes(ori_coors)$curved$curved |
|
|
604 |
} |
|
|
605 |
|
|
|
606 |
# scale the size and width |
|
|
607 |
scale_size_width(tmp_v, tmp_e, vertex_size_range, edge_width_range) |
|
|
608 |
|
|
|
609 |
# some custom parameters |
|
|
610 |
some_custom_paras(tmp_v, tmp_e, ...) |
|
|
611 |
|
|
|
612 |
# set pie |
|
|
613 |
pie_set_for_plot(tmp_v, pie_value, pie_color) |
|
|
614 |
if (is.null(pie_value) || !"pie" %in% tmp_v$shape) pie_legend <- FALSE |
|
|
615 |
if (is.null(pie_color)) { |
|
|
616 |
pie_color_list <- NULL |
|
|
617 |
} else { |
|
|
618 |
pie_color_list <- list(pie_color) |
|
|
619 |
} |
|
|
620 |
|
|
|
621 |
# show labels |
|
|
622 |
tmp_v <- get_show_labels(tmp_v, labels_num) |
|
|
623 |
|
|
|
624 |
# modules set |
|
|
625 |
module_set_for_plot(tmp_v, mark_module, mark_color) |
|
|
626 |
if (!mark_module) module_legend <- FALSE |
|
|
627 |
|
|
|
628 |
if (any(igraph::is.loop(go))) go <- clean_multi_edge_metanet(go) |
|
|
629 |
# main plot |
|
|
630 |
{ |
|
|
631 |
old_xpd <- graphics::par(mar = c(4, 2, 2, 2), xpd = TRUE) |
|
|
632 |
on.exit(graphics::par(old_xpd), add = TRUE) |
|
|
633 |
|
|
|
634 |
igraph::plot.igraph(go, |
|
|
635 |
layout = coors, |
|
|
636 |
vertex.size = tmp_v$size, |
|
|
637 |
vertex.color = tmp_v$color, |
|
|
638 |
vertex.shape = tmp_v$shape, |
|
|
639 |
vertex.label.color = tmp_v$label.color, |
|
|
640 |
edge.color = tmp_e$color, |
|
|
641 |
edge.lty = tmp_e$lty, |
|
|
642 |
edge.width = tmp_e$width, |
|
|
643 |
mark.groups = new_modu, |
|
|
644 |
mark.col = pcutils::add_alpha(module_color[names(new_modu)], mark_alpha), |
|
|
645 |
mark.border = module_color[names(new_modu)], |
|
|
646 |
vertex.pie = pie_value_list, |
|
|
647 |
vertex.pie.color = pie_color_list, |
|
|
648 |
..., |
|
|
649 |
vertex.frame.width = 0.5, |
|
|
650 |
main = main, |
|
|
651 |
rescale = rescale, |
|
|
652 |
vertex.label.font = 1, |
|
|
653 |
vertex.label.cex = 0.07 * tmp_v$size, |
|
|
654 |
vertex.label = tmp_v$label, |
|
|
655 |
edge.arrow.size = 0.3 * tmp_e$width * 3, |
|
|
656 |
edge.arrow.width = 0.6 * tmp_e$width * 3, |
|
|
657 |
edge.curved = edge_curved, |
|
|
658 |
margin = c(0, 0, 0, 0) |
|
|
659 |
) |
|
|
660 |
} |
|
|
661 |
|
|
|
662 |
# add module_label |
|
|
663 |
if (module_label) { |
|
|
664 |
rescale_flag <- TRUE |
|
|
665 |
params <- list(...) |
|
|
666 |
if ("rescale" %in% names(params)) { |
|
|
667 |
if (!params[["rescale"]]) rescale_flag <- FALSE |
|
|
668 |
} |
|
|
669 |
module_coors <- get_module_coors( |
|
|
670 |
tmp_v = tmp_v, ori_coors = ori_coors, |
|
|
671 |
module_label_just = module_label_just, rescale_flag = rescale_flag |
|
|
672 |
) |
|
|
673 |
|
|
|
674 |
n_module <- nrow(module_coors) |
|
|
675 |
module_label_cex <- rep(module_label_cex, n_module) |
|
|
676 |
module_label_color <- rep(module_label_color, n_module) |
|
|
677 |
for (i in seq_len(n_module)) { |
|
|
678 |
text( |
|
|
679 |
x = module_coors[i, "X"], y = module_coors[i, "Y"], |
|
|
680 |
labels = module_coors[i, "module"], |
|
|
681 |
cex = module_label_cex, col = module_label_color[i] |
|
|
682 |
) |
|
|
683 |
} |
|
|
684 |
} |
|
|
685 |
|
|
|
686 |
if (!legend) { |
|
|
687 |
return(invisible()) |
|
|
688 |
} |
|
|
689 |
|
|
|
690 |
if ("vertex.frame.width" %in% names(list(...))) { |
|
|
691 |
vertex_frame_width <- list(...)[["vertex.frame.width"]] |
|
|
692 |
} else { |
|
|
693 |
vertex_frame_width <- 0.5 |
|
|
694 |
} |
|
|
695 |
# produce legends |
|
|
696 |
if (grepl("skeleton", main)) attributes(tmp_v)$skeleton <- TRUE |
|
|
697 |
produce_c_net_legends( |
|
|
698 |
tmp_v, tmp_e, vertex_frame_width, |
|
|
699 |
legend_position, legend_number, legend_cex, |
|
|
700 |
node_size_text, edge_width_text, |
|
|
701 |
group_legend_title, group_legend_order, |
|
|
702 |
color_legend, color_legend_order, |
|
|
703 |
size_legend, size_legend_title, |
|
|
704 |
edge_legend, edge_legend_title, edge_legend_order, |
|
|
705 |
width_legend, width_legend_title, |
|
|
706 |
lty_legend, lty_legend_title, lty_legend_order, |
|
|
707 |
module_legend, module_legend_title, module_legend_order, module_color, mark_alpha, |
|
|
708 |
pie_legend, pie_legend_title, pie_legend_order, pie_color, ... |
|
|
709 |
) |
|
|
710 |
} |